Forum  Commercial Foru...  Commercial Foru...  ListView - sort for a control column
Previous Previous
 
Next Next
New Post 5/4/2011 7:24 AM
  sramirez@dynacal.com
508 posts
1st Level Poster


ListView - sort for a control column 

I have a listview that has a column "Name".  This column is set to a control column instead of a text column because I want the name to be a linklabel.

Is there a way to make the column sortable when clicking on the column header?

Thanks,
Shawn

 
New Post 5/4/2011 8:07 AM
  JamesC
850 posts
www.redcastle.co.uk
1st Level Poster




Re: ListView - sort for a control column 
Modified By JamesC  on 5/4/2011 1:49:47 PM)

Hi Shawn,

mmm, I would have thought that it would have sorted it by the text property anyway - I'm pretty sure it did that on a listview I had with texboxes in but anyway.......

to do this you can create a CustomListViewSorter and assign that to the listview.ListViewItemSorter instead of using the default - which only sorts alphabetically unless the listview is set to point to a datasource

I couldn't find a link to the article that described how to create one so the code is below - to add a sort by column type Control just extend the class lightly to include that sort type

<EDIT>

Found the link:

http://www.visualwebgui.com/Developers/KB/tabid/654/article/listviewitemsorter_for_strings_numbers_and_dates/Default.aspx?category=CodeB.Code3.Code3

</EDIT>

 
New Post 5/4/2011 11:52 AM
  sramirez@dynacal.com
508 posts
1st Level Poster


Re: ListView - sort for a control column 

I have a custom sorter that Palli gave me a short time ago.  However, it doesn't handle a linklabel in a control column.  Do I add an ifelse in there to do a check for objColumn.Type = ListViewColumnType.Control?  If so what do I put inside it to handle a linklabel?

Public Class myListViewSorter
    Implements System.Collections.IComparer

    Private mobjListView As ListView
    Public Sub New(ByVal LI As ListView)
        mobjListView = LI
    End Sub
    Private Function GetSortingColumns() As ICollection
        Dim objSortData As ColumnHeaderSortingData = New ColumnHeaderSortingData(mobjListView)
        Return objSortData.SortingColumns
    End Function
    Public Function Compare(ByVal objObjectA As Object, ByVal objObjectB As Object) As Integer Implements System.Collections.IComparer.Compare
        ' Get list viewitems
        Dim objItemA As ListViewItem = TryCast(objObjectA, ListViewItem)
        Dim objItemB As ListViewItem = TryCast(objObjectB, ListViewItem)
        Dim objSortingColumns As ICollection = Me.GetSortingColumns

        ' Check valid items
        If objItemA IsNot Nothing AndAlso objItemB IsNot Nothing Then
            ' Check that there are columns
            If objSortingColumns.Count = 0 Then
                Return 0
            Else
                ' Loop all sorting columns
                For Each objColumn As ColumnHeader In objSortingColumns
                    ' Get sorting direction
                    Dim intDirection As Integer = If((objColumn.SortOrder = SortOrder.Ascending), 1, -1)

                    ' The comparison result
                    Dim intResult As Integer = 0
                    If objColumn.Type = ListViewColumnType.Number Then
                        intResult = CType(objItemA.SubItems(objColumn.Index).Text, Integer).CompareTo(CType(objItemB.SubItems(objColumn.Index).Text, Integer))
                    Else
                        intResult = objItemA.SubItems(objColumn.Index).Text.CompareTo(objItemB.SubItems(objColumn.Index).Text)
                    End If
                    If intResult <> 0 Then
                        Return intResult * intDirection
                    End If
                Next
                Return 0
            End If
        Else
            Return 0
        End If
    End Function
End Class

 
New Post 5/4/2011 12:46 PM
  JamesC
850 posts
www.redcastle.co.uk
1st Level Poster




Re: ListView - sort for a control column 

 Hi Shawn,

I'm not at work at the moment but will be in the morning (about 12 hours from now) I will update the example on the web and the code that Palli supplied you with to handle a few types of controls - including linklabels and post the code (C# & VB) on here for you,

but yes scanning through the code that you posted it looks to be just a case of adding an extra Else If Then - but you do still need to check for control type to get the correct property from it and type of sorting to perform - and watch out for different control types being in the column!! ~ (if you want it to be generic code anyway)

cheers james

 
New Post 5/4/2011 1:46 PM
  palli
14304 posts
1st Level Poster




Re: ListView - sort for a control column 

Hi Shawn,

You've forced me to extend the sorter class so much, that I see no other option other than adding it as an official code sample ... which I will probably do shortly

It is fairly easy to extend the class to sort about anything you want it to, you just need to define the logic on what to sort each time.

The sample below extends the sorter class to sort on the Text property of any control that you will find within a Control type column of a ListView, and in case it's a Panel control, take it one step further and sort by the first control contained within the panel. The sample shows a ListView with 4 columns, one Text, one Number, one Control with a LinkLabel and finally one Control with a Panel that contains a Textbox.

You can extend the GetControlSortString() function at will to include the logic that you see fit for your case. If you for instance rather want to sort the LinkLabel on the Url, instead of the Text property, then it's trivial to add a new if statement to check for a LinkLabel and then return the Url.

 

Imports Gizmox.WebGUI.Forms
Imports Gizmox.WebGUI.Common
Imports Gizmox.WebGUI.Forms.ListViewItem
 
Public Class Form2
 
    Private ListView1 As ListView
 
    Private Sub BuildColumns()
        Dim Ch As ColumnHeader = New ColumnHeader
        Ch.Text = "Text"
        Ch.Type = ListViewColumnType.Text
        Ch.Width = 100
        ListView1.Columns.Add(Ch)
 
        Ch = New ColumnHeader
        Ch.Text = "Number"
        Ch.Type = ListViewColumnType.Number
        Ch.Width = 100
        ListView1.Columns.Add(Ch)
 
        Ch = New ColumnHeader
        Ch.Text = "LinkLabel"
        Ch.Type = ListViewColumnType.Control
        Ch.Width = 100
        ListView1.Columns.Add(Ch)
 
        Ch = New ColumnHeader
        Ch.Text = "Panel"
        Ch.Type = ListViewColumnType.Control
        Ch.Width = 100
        ListView1.Columns.Add(Ch)
    End Sub
    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ListView1 = New ListView()
        ListView1.Dock = DockStyle.Fill
        Me.Controls.Add(ListView1)
        BuildColumns()
 
        ' Load data
        For i As Integer = 1 To 100
            Dim LI As ListViewItem = New ListViewItem()
            LI.SubItems.Add(i.ToString())
            LI.SubItems.Add(i)
            LI.SubItems.Add(New LinkLabel("LinkLabel " + i.ToString(), "http://www.visualwebgui.com"))
            Dim P As Panel = New Panel()
            Dim T As TextBox = New TextBox()
            T.Dock = DockStyle.Fill
            P.Controls.Add(T)
            T.Text = "TextBox " + i.ToString()
            LI.SubItems.Add(P)
            ListView1.Items.Add(LI)
        Next
        ListView1.ListViewItemSorter = New MyLISorter(Me.ListView1)
    End Sub
 
 
 
    Public Class MyLISorter
        Implements System.Collections.IComparer
 
        Private mobjListView As ListView
 
        Public Sub New(ByVal LI As ListView)
            mobjListView = LI
        End Sub
 
        Private Function GetSortingColumns() As ICollection
            Dim objSortData As ColumnHeaderSortingData = New ColumnHeaderSortingData(mobjListView)
            Return objSortData.SortingColumns
        End Function
 
        Public Function GetControlSortString(ByVal C As Control) As String
            ' Customize logic at will. Return string suitable for sorting.
            If C.GetType() Is GetType(Panel) Then
                Dim P As Panel = CType(C, Panel)
                If P.Controls.Count = 0 Then
                    ' If no controls on panel, empty string
                    Return ""
                Else
                    ' Sort by the first control on the panel
                    Return GetControlSortString(P.Controls(0))
                End If
 
            Else
                Return C.Text
            End If
        End Function
        Public Function Compare(ByVal objObjectA As Object, ByVal objObjectB As Object) As Integer Implements System.Collections.IComparer.Compare
            ' Get list viewitems
            Dim objItemA As ListViewItem = TryCast(objObjectA, ListViewItem)
            Dim objItemB As ListViewItem = TryCast(objObjectB, ListViewItem)
 
            Dim objSortingColumns As ICollection = Me.GetSortingColumns
 
            ' Check valid items
            If objItemA IsNot Nothing AndAlso objItemB IsNot Nothing Then
                ' Check that there are columns
                If objSortingColumns.Count = 0 Then
                    Return 0
                Else
                    ' Loop all sorting columns
                    For Each objColumn As ColumnHeader In objSortingColumns
                        ' Get sorting direction
                        Dim intDirection As Integer = If((objColumn.SortOrder = SortOrder.Ascending), 1, -1)
 
                        ' The comparison result
                        Dim intResult As Integer = 0
                        If objColumn.Type = ListViewColumnType.Number Then
                            intResult = CType(objItemA.SubItems(objColumn.Index).Text, Integer).CompareTo(CType(objItemB.SubItems(objColumn.Index).Text, Integer))
                        ElseIf objColumn.Type = ListViewColumnType.Control Then
                            ' Compare controls
                            Dim objControlA, objControlB As ListViewSubControlItem
                            objControlA = objItemA.SubItems(objColumn.Index)
                            objControlB = objItemB.SubItems(objColumn.Index)
                            intResult = GetControlSortString(objControlA.Control).CompareTo(GetControlSortString(objControlB.Control))
                        Else
                            ' Compare Text property by default
                            intResult = objItemA.SubItems(objColumn.Index).Text.CompareTo(objItemB.SubItems(objColumn.Index).Text)
                        End If
                        If intResult <> 0 Then
                            Return intResult * intDirection
                        End If
                    Next
                    Return 0
                End If
            Else
                Return 0
            End If
        End Function
 
    End Class
End Class

Hope this gives you some ideas,

Palli

 


Páll Björnsson - Visual WebGui support team - Email: support@visualwebgui.com
 
Previous Previous
 
Next Next
  Forum  Commercial Foru...  Commercial Foru...  ListView - sort for a control column
.NET HTML5 Web, Cloud and Mobile application delivery | Sitemap | Terms of Use | Privacy Statement | Copyright © 2005-2012 Visual WebGui®       Visual WebGui weblog on ASP.NET Gizmox Blog Visual WebGui Group on LinkedIn Visual WebGui updates on Twitter Visual WebGui Page on Facebook Visual WebGui YouTube Channel Visual WebGui Platform News RSS