Problem with listviewsorter class

S

sonu

Hi,


I have a problem regarding use of a ListviewSorter class which is used
to sort the items in the
listview.

Basically I have a listview with three columns as "Name","Size" and
"Date/Time" having datatype as text,Integer and datetime.

I need to sort the values in the listview depending upon whicj column
is currently clicked.
The problem is while sorting the integer values.

Function for comparing the values is something like.

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

listViewItem1 = CType(x, ListViewItem)
listViewItem2 = CType(y, ListViewItem)

If columnToSort = ListColumn.NAME Then 'compare the two data depending
upon text values
compareResult =
ObjectCompare.Compare(listViewItem1.SubItems(columnToSort).Text,
llistViewItem2.SubItems(columnToSort).Text)

ElseIf columnToSort = ListColumn.SIZE Then 'compare the two data
depending upon numeric values

compareResult = Val(listViewItem1.SubItems(columnToSort).Text) >
Val(listViewItem2.SubItems(columnToSort).Text)

... code to compare dates
If OrderOfSort = SortOrder.Ascending Then
Return compareResult 'Ascending sort is selected, return
normal result of compare operation
ElseIf OrderOfSort = SortOrder.Descending Then
Return (-compareResult) 'Descending sort is selected,
return negative result of compare operation
Else
Return 0
End If

End function

My listview gets sort only once when selected the option sort by size

What could be the problem ..

Thanks in advance
 
G

Greg Burns

sonu said:
I have a problem regarding use of a ListviewSorter class which is used
to sort the items in the
listview.

Here is the code I use.

Enum PCOColumns
PersonID
Result
Type
EffectiveDate
SubmitDate
End Enum

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.

InitializeComponent()

....

' Create an instance of a ListView column sorter and assign it
' to the ListView control.
lvwColumnSorter2 = New ListViewColumnSorter
Me.lvwPCOs.ListViewItemSorter = lvwColumnSorter2

....
End Sub

Private Sub lvwPCOs_ColumnClick(ByVal sender As System.Object, ByVal e As
System.Windows.Forms.ColumnClickEventArgs) Handles lvwPCOs.ColumnClick
Select Case e.Column
Case PCOColumns.PersonID
lvwColumnSorter2.SortType =
ListViewColumnSorter.enumSortType.NumericSort
Case PCOColumns.SubmitDate, PCOColumns.EffectiveDate
lvwColumnSorter2.SortType =
ListViewColumnSorter.enumSortType.DateSort
Case Else
lvwColumnSorter2.SortType =
ListViewColumnSorter.enumSortType.AlphaSort
End Select

' Determine if the clicked column is already the column that is
' being sorted.
If (e.Column = lvwColumnSorter2.SortColumn) Then
' Reverse the current sort direction for this column.
If (lvwColumnSorter2.Order = SortOrder.Ascending) Then
lvwColumnSorter2.Order = SortOrder.Descending
Else
lvwColumnSorter2.Order = SortOrder.Ascending
End If
Else
' Set the column number that is to be sorted; default to
ascending.
lvwColumnSorter2.SortColumn = e.Column
lvwColumnSorter2.Order = SortOrder.Ascending
End If

' Perform the sort with these new sort options.
Me.lvwPCOs.Sort()

End Sub


ListViewColumnSorter.vb:

Imports System.Collections
Imports System.Windows.Forms

Public Class ListViewColumnSorter
Implements System.Collections.IComparer

Private ColumnToSort As Integer
Private OrderOfSort As SortOrder
Private ObjectCompare As CaseInsensitiveComparer
Private TypeOfSort As enumSortType

Enum enumSortType
AlphaSort
NumericSort
DateSort
End Enum

Public Sub New()
' Initialize the column to '0'.
ColumnToSort = 0

' Initialize the sort order to 'none'.
OrderOfSort = SortOrder.None

' Initialize the CaseInsensitiveComparer object.
ObjectCompare = New CaseInsensitiveComparer

' Initialize the default column type to be Alpha.
TypeOfSort = enumSortType.AlphaSort
End Sub

Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer
Implements IComparer.Compare
Dim compareResult As Integer
Dim listviewX As ListViewItem
Dim listviewY As ListViewItem

' Cast the objects to be compared to ListViewItem objects.
listviewX = CType(x, ListViewItem)
listviewY = CType(y, ListViewItem)

' Compare the two items.
Select Case TypeOfSort
Case enumSortType.AlphaSort
compareResult =
ObjectCompare.Compare(listviewX.SubItems(ColumnToSort).Text,
listviewY.SubItems(ColumnToSort).Text)

Case enumSortType.NumericSort
Dim intx As Integer =
CInt(listviewX.SubItems(ColumnToSort).Text)
Dim inty As Integer =
CInt(listviewY.SubItems(ColumnToSort).Text)

If intx = inty Then
compareResult = 0
ElseIf intx > inty Then
compareResult = 1
Else
compareResult = -1
End If

Case enumSortType.DateSort
Dim datex As Date =
Convert.ToDateTime(listviewX.SubItems(ColumnToSort).Text)
Dim datey As Date =
Convert.ToDateTime(listviewY.SubItems(ColumnToSort).Text)

If datex = datey Then
compareResult = 0
ElseIf datex > datey Then
compareResult = 1
Else
compareResult = -1
End If
End Select


' Calculate the correct return value based on the object
' comparison.
If (OrderOfSort = SortOrder.Ascending) Then
' Ascending sort is selected, return typical result of
' compare operation.
Return compareResult
ElseIf (OrderOfSort = SortOrder.Descending) Then
' Descending sort is selected, return negative result of
' compare operation.
Return (-compareResult)
Else
' Return '0' to indicate that they are equal.
Return 0
End If
End Function

Public Property SortColumn() As Integer
Set(ByVal Value As Integer)
ColumnToSort = Value
End Set

Get
Return ColumnToSort
End Get
End Property

Public Property Order() As SortOrder
Set(ByVal Value As SortOrder)
OrderOfSort = Value
End Set

Get
Return OrderOfSort
End Get
End Property

Public Property SortType() As enumSortType
Get
Return TypeOfSort
End Get
Set(ByVal Value As enumSortType)
TypeOfSort = Value
End Set
End Property
End Class

Greg
 
K

Kalpesh

Hi,

Are you setting the value of "columnToSort " when user clicks any
column header ?
Also, are you setting the value of sort-order to identify whether user
wishes to sort ascending or descending ?

I assume you are doing it once in some initialization method.
You need to set the values again when user clicks any of the column
header

HTH
Kalpesh
 
G

Greg Burns

Forgot to mention...

You need to also make a form level private variable:

Private lvwColumnSorter2 As ListViewColumnSorter

My listview's name is lvwPCOs

I am giving enums to my column names so I can refer to them by name in the
ColumnClick event. Makes it easier to asjust if I rearrange them or add new
ones.

Greg
 
K

Kalpesh

Are you able to step through the code in Compare method every time the
column header is clicked ?

Kalpesh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top