|
-
Feb 18th, 2010, 01:13 PM
#1
Thread Starter
Member
Very Confussed - Variable changing?
Hey All,
The following procedures sorts a listview column based on what the tag is, 'Numeric', 'String' or 'Date'. When you click on the column header the sort procedure kicks in. On the first click it will sort ascending and on the second click it will sort descending.
My problem is that when I click a second time it won't sort descending but re-sorts ascending again.
It appears when the sortorder is passed to the ListViewColumnSorter.vb classes it changes back to ascending even though it's called as descending. I've bolded the offending variables using a Numeric search.
Now here's the really iritaing thing, I have exactly the same code in another application and it works perfectly?!?!
Code:
Private Sub lvwResults_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lvwResults.ColumnClick
SortMyListView(Me.lvwResults, e.Column, , True)
LedgerStyle()
End Sub
Code:
#Region "SortListView"
Friend Sub SortMyListView(ByVal ListViewToSort As ListView, ByVal ColumnNumber As Integer, Optional ByVal Resort As Boolean = False, Optional ByVal ForceSort As Boolean = False)
' Sorts a list view column by string, number, or date. The three types of sorts must be specified within the listview columns "tag" property unless the ForceSort option is enabled.
' ListViewToSort - The listview to sort
' ColumnNumber - The column number to sort by
' Resort - Resorts a listview in the same direction as the last sort
' ForceSort - Forces a sort even if no listview tag data exists and assumes a string sort. If this is false (default) and no tag is specified the procedure will exit
Dim SortOrder As SortOrder
Static LastSortColumn As Integer = -1
Static LastSortOrder As SortOrder = SortOrder.Ascending
If Resort = True Then
SortOrder = LastSortOrder
Else
If LastSortColumn = ColumnNumber Then
If LastSortOrder = SortOrder.Ascending Then
SortOrder = SortOrder.Descending
Else
SortOrder = SortOrder.Ascending
End If
Else
SortOrder = SortOrder.Ascending
End If
End If
' In case a tag wasn't specified check if we should force a string sort
If String.IsNullOrEmpty(CStr(ListViewToSort.Columns(ColumnNumber).Tag)) Then
If ForceSort = True Then
ListViewToSort.Columns(ColumnNumber).Tag = "String"
Else
' don't sort since no tag was specified.
Exit Sub
End If
End If
Select Case ListViewToSort.Columns(ColumnNumber).Tag.ToString
Case "Numeric"
ListViewToSort.ListViewItemSorter = New
ListViewNumericSort(ColumnNumber, SortOrder)
Case "Date"
ListViewToSort.ListViewItemSorter = New ListViewDateSort(ColumnNumber, SortOrder)
Case "String"
ListViewToSort.ListViewItemSorter = New ListViewStringSort(ColumnNumber, SortOrder)
End Select
LastSortColumn = ColumnNumber
LastSortOrder = SortOrder
ListViewToSort.ListViewItemSorter = Nothing
End Sub
#End Region
ListViewColumnSorter.vb
Code:
Imports System.Collections
Imports System.Windows.Forms
Public Class ListViewColumnSorter
Implements IComparer
Public Enum SortOrder
Ascending
Descending
End Enum
Private mSortColumn As Integer
Private mSortOrder As SortOrder
Public Sub New(ByVal sortColumn As Integer, ByVal sortOrder As SortOrder)
mSortColumn = sortColumn
mSortOrder = sortOrder
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
Dim Result As Integer
Dim ItemX As ListViewItem
Dim ItemY As ListViewItem
ItemX = CType(x, ListViewItem)
ItemY = CType(y, ListViewItem)
If mSortColumn = 0 Then
Result = DateTime.Compare(CType(ItemX.Text, DateTime), CType(ItemY.Text, DateTime))
Else
Result = DateTime.Compare(CType(ItemX.SubItems(mSortColumn).Text, DateTime), CType(ItemY.SubItems(mSortColumn).Text, DateTime))
End If
If mSortOrder = SortOrder.Descending Then
Result = -Result
End If
Return Result
End Function
End Class
Public Class ListViewStringSort
Implements IComparer
Private mSortColumn As Integer
Private mSortOrder As SortOrder
Public Sub New(ByVal sortColumn As Integer, ByVal sortOrder As SortOrder)
mSortColumn = sortColumn
mSortOrder = sortOrder
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
Dim Result As Integer
Dim ItemX As ListViewItem
Dim ItemY As ListViewItem
ItemX = CType(x, ListViewItem)
ItemY = CType(y, ListViewItem)
If mSortColumn = 0 Then
Result = ItemX.Text.CompareTo(ItemY.Text)
Else
Result = ItemX.SubItems(mSortColumn).Text.CompareTo(ItemY.SubItems(mSortColumn).Text)
End If
If mSortOrder = SortOrder.Descending Then
Result = -Result
End If
Return Result
End Function
End Class
Public Class ListViewNumericSort
Implements IComparer
Private mSortColumn As Integer
Private mSortOrder As SortOrder
Public Sub New(ByVal sortColumn As
Integer, ByVal sortOrder As SortOrder) '<------This is when it changes
mSortColumn = sortColumn
mSortOrder = sortOrder
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
Dim Result As Integer
Dim ItemX As ListViewItem
Dim ItemY As ListViewItem
ItemX = CType(x, ListViewItem)
ItemY = CType(y, ListViewItem)
If mSortColumn = 0 Then
Result = Decimal.Compare(CType(ItemX.Text, Decimal), CType(ItemY.Text, Decimal))
Else
Result = Decimal.Compare(CType(ItemX.SubItems(mSortColumn).Text, Decimal), CType(ItemY.SubItems(mSortColumn).Text, Decimal))
End If
If mSortOrder = SortOrder.Descending Then
Result = -Result
End If
Return Result
End Function
End Class
Public Class ListViewDateSort
Implements IComparer
Private mSortColumn As Integer
Private mSortOrder As SortOrder
Public Sub New(ByVal sortColumn As Integer, ByVal sortOrder As SortOrder)
mSortColumn = sortColumn
mSortOrder = sortOrder
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
Dim Result As Integer
Dim ItemX As ListViewItem
Dim ItemY As ListViewItem
ItemX = CType(x, ListViewItem)
ItemY = CType(y, ListViewItem)
If mSortColumn = 0 Then
Result = DateTime.Compare(CType(ItemX.Text, DateTime), CType(ItemY.Text, DateTime))
Else
Result = DateTime.Compare(CType(ItemX.SubItems(mSortColumn).Text, DateTime), CType(ItemY.SubItems(mSortColumn).Text, DateTime))
End If
If mSortOrder = SortOrder.Descending Then
Result = -Result
End If
Return Result
End Function
End Class
Last edited by nige; Feb 18th, 2010 at 02:09 PM.
-
Feb 18th, 2010, 02:01 PM
#2
Re: Very Confussed - Variable changing?
That code is seriously annoying to read on my screen as I can't get that main snippet to fit within the screen, so I can't scroll in both directions at any one time. Still, put a breakpoint on this line:
If Resort = True Then
And step forwards from there. I don't use static variables, but it sure looks to me like you always change the sort order to Ascending every time you enter the sub, which means that it wouldn't flip flop the way you expect it to.
My usual boring signature: Nothing
 
-
Feb 18th, 2010, 02:11 PM
#3
Thread Starter
Member
Re: Very Confussed - Variable changing?
Hey Shaggy...
I've put a carriage return on the offending lines so you should see the bolded text. The second bolded section of code is where the sortorder = 'Descending' but when it steps to the third section of code (at the bolded sortorder) it becomes Ascending.
As I said above, the code works perfectly in another program I have.
I just can't understand what's going on?
-
Feb 18th, 2010, 02:25 PM
#4
Re: Very Confussed - Variable changing?
I think the problem is that you have 4 different SortOrder enums... But I'm not 100% sure though. What I'd do is to consolidate all 4 column sorter classes into a single 1, and change the contructor to accept 1 more parameter which indicates the data type of the column being sorted. In the Compare function, you do a select case on the data type and do the compare accordingly.
Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
- Abraham Lincoln -
-
Feb 18th, 2010, 02:31 PM
#5
Thread Starter
Member
Re: Very Confussed - Variable changing?
I think the problem is that you have 4 different SortOrder enums... But I'm not 100% sure though. What I'd do is to consolidate all 4 column sorter classes into a single 1, and change the contructor to accept 1 more parameter which indicates the data type of the column being sorted. In the Compare function, you do a select case on the data type and do the compare accordingly.
Hey Stanav,
I've remarked out all the other classes except the numeric one and re ran the code. Unfortunately the same problem occurs?
N
-
Feb 18th, 2010, 02:41 PM
#6
Thread Starter
Member
Re: Very Confussed - Variable changing?
I've also started up a completely new application added a listview used the exact same code and it works perfectly?
-
Feb 18th, 2010, 02:50 PM
#7
Thread Starter
Member
Re: Very Confussed - Variable changing?
Ok I've now got it working. I copied the Class to my main .vb file and exlcuded the ListViewColumnSorter.vb from the project.
It now works?????
Very strange indeed, can anyone explain?
Last edited by nige; Feb 18th, 2010 at 02:54 PM.
Reason: sp
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|