Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

List View Sort

Status
Not open for further replies.

Nickaroo

MIS
Mar 24, 2003
21
US
I am trying to sort Columns in Listview. I have used Comparer in my code. I don't understand how to sort a Numerical column....(file.length, third column)
Any help is greatly appreciated.

Here is my code.

Thanks
Nick

Class ListViewItemComparer
Implements IComparer

Private col As Integer

Public Sub New()
col = 0
End Sub

Public Sub New(ByVal column As Integer)
col = column
End Sub

Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
Implements IComparer.Compare
Return [String].Compare(CType(x, ListViewItem).SubItems(col).Text, CType(y, ListViewItem).SubItems(col).Text)

End Function
End Class
#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents ListView1 As System.Windows.Forms.ListView
Friend WithEvents ReSize1 As LarcomAndYoung.Windows.Forms.ReSize
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container
Me.ListView1 = New System.Windows.Forms.ListView
Me.ReSize1 = New LarcomAndYoung.Windows.Forms.ReSize(Me.components)
Me.SuspendLayout()
'
'ListView1
'
Me.ListView1.Location = New System.Drawing.Point(56, 40)
Me.ListView1.Name = "ListView1"
Me.ListView1.Size = New System.Drawing.Size(688, 304)
Me.ListView1.TabIndex = 0
'
'ReSize1
'
Me.ReSize1.About = Nothing
Me.ReSize1.AutoCenterFormOnLoad = False
Me.ReSize1.Enabled = True
Me.ReSize1.HostContainer = Me
Me.ReSize1.InitialHostContainerHeight = 374
Me.ReSize1.InitialHostContainerWidth = 808
Me.ReSize1.Tag = Nothing
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(808, 374)
Me.Controls.Add(Me.ListView1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub

#End Region


Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Fi As FileInfo
Dim Sitem As New ListViewItem
Dim File As String
ChDir("c:\temp")
ListView1.View = View.Details
ListView1.GridLines = True
ListView1.MultiSelect = False
ListView1.FullRowSelect = True
ListView1.AllowColumnReorder = True
ListView1.Columns.Add("File Name", 400, HorizontalAlignment.Left)
ListView1.Columns.Add("Date & time", 150, HorizontalAlignment.Left)
ListView1.Columns.Add("Size", 100, HorizontalAlignment.Left)
For Each File In Directory.GetFiles(Directory.GetCurrentDirectory)
Fi = New FileInfo(File)
Sitem = ListView1.Items.Add(Fi.Name)
Sitem.SubItems.Add(Fi.CreationTime)
Sitem.SubItems.Add(Fi.Length)
Next

End Sub

Private Sub ListView1_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView1.ColumnClick
ListView1.ListViewItemSorter = New ListViewItemComparer(e.Column)
ListView1.Sort()
End Sub

End Class

 
In my Comparer, I check for col(s) that require "numerical" character sorting and PadLeft for the MAX characters, after Trim, in either string
If mintcol = idxSize Then
sX = sX.Trim
sY = sY.Trim
Dim l As Integer = System.Math.Max(sX.Length, sY.Length)
returnVal = [String].Compare(sX.PadLeft(l, "0"c), _
sY.PadLeft(l, "0"c), True)
Else
returnVal = [String].Compare(sX, sY, True)
End If
See below.
Code:
' Outer Class
    Private Const idxDateTime As Short = 1
    Private Const idxSize As Short = 2
    Private Const idxPath As Short = 3
    Private Const idxElement As Short = 4
Class ListViewItemComparer
        Implements IComparer
        Private mintcol As Integer
        Private mintSortOrder As System.Windows.Forms.SortOrder = SortOrder.Ascending
        Private mblnIgnoreCase As Boolean
        Friend Sub New()
            mintcol = 0
            mintSortOrder = SortOrder.Ascending
            mblnIgnoreCase = False
        End Sub

        Friend Sub New(ByVal column As Integer, _
                    ByVal SortOrder As System.Windows.Forms.SortOrder, _
                    Optional ByVal IgnoreCase As Boolean = False)

            mintcol = column
            mintSortOrder = SortOrder
            mblnIgnoreCase = IgnoreCase

        End Sub

        Friend Function Compare(ByVal x As Object, _
                                ByVal y As Object) _
                            As Integer _
                        Implements System.Collections.IComparer.Compare

            Dim returnVal As Integer = -1
            Dim oX As ListViewItem = DirectCast(x, ListViewItem)
            Dim oY As ListViewItem = DirectCast(y, ListViewItem)
            Dim lvc As ListView.ListViewItemCollection = _
                        oX.ListView.Items
            Dim iX As Integer = oX.Index
            Dim iY As Integer = oY.Index
            Dim sX As String = oX.SubItems(mintcol).Text
            Dim sY As String = oY.SubItems(mintcol).Text

            If mintcol = idxSize Then
                sX = sX.Trim
                sY = sY.Trim
                Dim l As Integer = System.Math.Max(sX.Length, sY.Length)
                returnVal = [String].Compare(sX.PadLeft(l, "0"c), _
                                             sY.PadLeft(l, "0"c), True)
            Else
                returnVal = [String].Compare(sX, sY, True)
            End If

            If mintcol <> 0 Then
                If returnVal = 0 Then
                    sX = lvc(iX).SubItems(0).Text
                    sY = lvc(iY).SubItems(0).Text
                    returnVal = [String].Compare(sX, sY, True)
                End If
            End If

            If mintcol <> idxPath Then
                If returnVal = 0 Then
                    sX = lvc(iX).SubItems(idxPath).Text
                    sY = lvc(iY).SubItems(idxPath).Text
                    returnVal = [String].Compare(sX, sY, True)
                End If
            End If
            If mintSortOrder = SortOrder.Descending Then returnVal = -returnVal

            Return returnVal

        End Function
    End Class

Forms/Controls Resizing/Tabbing
Compare Code
Generate Sort Class in VB
Check To MS)
 
Thanks, That works great...One other quick question though...How can i get a date(column) field sorted...

 
Hi dudes...

I have a problem here.. kiond of weird with a listview, duno if any of u can help me out.
Im trying to sort a listview with numerical values.

So, if i put the following values:
42.3, 42.4, 42.1 and 41.0 i get the files sorted correctly as 42.4,42.3,42.1 and 41.0 but if i put those values but instead of 41.0 i just put 41, i get the following results:
41, 42.4,42.3,and 42.1 , in that order... i dunno why...

Here is the part of the code that adds the valkues to the listview:
valactualfrec = txtfrecval.Text
frecactual = txtvalfrec.Text
lstvfrec.Sorting = SortOrder.Descending
lstvfrec.Items.Add(New ListViewItem(valactualfrec)).SubItems.Add(frecactual)
numelem = lstvfrec.Items.Count - 1
sumatoriaf = sumatoriaf + frecactual

Hope anyone knows, thanks in advance guys
 
Got it working folks...
just converted the data type to decimal and changed this line
lstvfrec.Items.Add(New ListViewItem((valactualfrec).ToString("#0.00"))).SubItems.Add(frecactual)
:)

nw i would like to know if there is a way to avoid duplicates on the items...
any ideas?

thanks :)
 
Nice and helpfull !

i have a question though, how can you prevent your listview item to scrollback to the horizontal origin?

I mean let's say i have a listview that has ten columns and that i need to scroll rightwards to reach the tenth column, how can i prevent the listview to scrollback to the first column when i sort the listview on the tenth? because this is what actually happens on my listview..

it is not a real issue but it would be nice (and professional looking) if it didn't.

thanks
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top