使用ListView
控件,您可以指定要排序的列,并且可以随时使用sort()
的方法。
但是,这只允许单列排序。
我很想排序,首先是A列,然后是F列,它们是相同的。
我发现了一些在线编写的自定义比较类,但想知道stackoverflow是否可以显示更清晰的方式。再加上这个可以帮助其他人在将来寻找它:)
有关如何理解此事的任何建议或示例。
答案 0 :(得分:5)
所以,在玩完之后,我想出的答案是通过ListViewItemComparer
界面写一个IComparer
课程。
然后我覆盖了Compare()
方法,现在可以返回-1,0或1,具体取决于第一列与第二列之间的比较,然后等于第二列。
最后我觉得很干净。
答案 1 :(得分:2)
与几乎所有任务一样,ObjectListView(.NET WinForms ListView的开源包装器)使得使用ListView变得更加容易。
ObjectListView具有SecondarySortColumn
和SecondarySortOrder
属性,可以完全按照您的要求进行操作。
如果您想进行更好的排序,可以安装CustomSorter
。看看this recipe
答案 2 :(得分:2)
@MarkMayo,我通过支持二级/优先级列排序的ListViewItemComparer
接口创建了自己的排序器类IComparer
。
我覆盖Compare()
方法以支持数字,日期和广告不区分大小写的字符串比较。
首先对您希望的列进行排序,如果两个比较值相同,则将第二列作为排序的参考,从而进行二次排序。
您只需要包含此分拣机类并使用以下示例VB.Net代码修改Form的Listview ColumnClick
事件:
ListViewItemComparer类
Imports System.Collections
''' <summary>
''' This class is an implementation of the 'IComparer' interface.
''' </summary>
Public Class ListViewColumnSorter
Implements IComparer
''' <summary>
''' Specifies the column to be sorted
''' </summary>
Private ColumnToSort As Integer
''' <summary>
''' Specifies the secondary column to be sorted
''' </summary>
Private SecondaryColumnToSort As Integer = -1
''' <summary>
''' Specifies the order in which to sort (i.e. 'Ascending').
''' </summary>
Private OrderOfSort As SortOrder
''' <summary>
''' Class constructor. Initializes various elements
''' </summary>
Public Sub New(ByVal column_number As Integer, ByVal sort_order As SortOrder)
ColumnToSort = column_number
OrderOfSort = sort_order
End Sub
''' <summary>
''' Class constructor. Initializes various elements
''' </summary>
Public Sub New(ByVal column_number As Integer, ByVal sort_order As SortOrder, ByVal secondary_column_number As Integer)
ColumnToSort = column_number
SecondaryColumnToSort = secondary_column_number
OrderOfSort = sort_order
End Sub
''' <summary>
''' This method is inherited from the IComparer interface. It compares the two objects passed and support secondary column comparison
''' </summary>
''' <param name="x">First object to be compared</param>
''' <param name="y">Second object to be compared</param>
''' <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
Public Function Compare(x As Object, y As Object) As Integer Implements IComparer.Compare
Dim compareResult As Integer
Dim listviewX As ListViewItem, listviewY As ListViewItem
' Cast the objects to be compared to ListViewItem objects
listviewX = DirectCast(x, ListViewItem)
listviewY = DirectCast(y, ListViewItem)
' Compare the two items
Dim x1 As Object = listviewX.SubItems(ColumnToSort)
Dim y1 As Object = listviewY.SubItems(ColumnToSort)
' Use .tag for comparison if not empty
If (x1.Tag IsNot vbNullString) And (y1.Tag IsNot vbNullString) Then
compareResult = ObjectComparer(x1.Tag, y1.Tag)
Else
compareResult = ObjectComparer(x1.Text, y1.Text)
End If
'require secondary column compare?
If (compareResult = 0 And SecondaryColumnToSort >= 0 And SecondaryColumnToSort <> ColumnToSort) Then
' Compare the two items
Dim x2 As Object = listviewX.SubItems(SecondaryColumnToSort)
Dim y2 As Object = listviewY.SubItems(SecondaryColumnToSort)
' Use .tag for comparison if not empty
If (x2.Tag IsNot vbNullString) And (y2.Tag IsNot vbNullString) Then
compareResult = ObjectComparer(x2.Tag, y2.Tag)
Else
compareResult = ObjectComparer(x2.Text, y2.Text)
End If
End If
' Calculate correct return value based on object comparison
If OrderOfSort = SortOrder.Ascending Then
' Ascending sort is selected, return normal 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 they are equal
Return 0
End If
End Function
''' <summary>
''' This method compares the two objects passed. Object supported are numeric, dates and string
''' </summary>
''' <param name="x">First object to be compared</param>
''' <param name="y">Second object to be compared</param>
''' <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
Private Function ObjectComparer(x As Object, y As Object) As Integer
Dim compareResult As Integer
If IsNumeric(x) And IsNumeric(y) Then 'comparing numbers
compareResult = Val(x).CompareTo(Val(y))
ElseIf IsDate(x) And IsDate(y) Then 'comparing dates
compareResult = DateTime.Parse(x).CompareTo(DateTime.Parse(y))
Else 'comparing string
Dim ObjectCompare As New CaseInsensitiveComparer
compareResult = ObjectCompare.Compare(x.ToString, y.ToString)
End If
Return compareResult
End Function
End Class
Windows窗体的Listview ColumnClick
Private prevColumnClick As Integer 'to store previous sorted column number
Private secondary_column_to_sort As Integer = 0 'column 0
Private Sub lvLog_ColumnClick(sender As Object, e As ColumnClickEventArgs) Handles lvLog.ColumnClick
Dim myListView As ListView = DirectCast(sender, ListView)
Dim sort_order As System.Windows.Forms.SortOrder
If myListView.Columns(e.Column).Tag Is Nothing Then
sort_order = SortOrder.Ascending
Else
' Get previous sort order information from columns .tag
sort_order = DirectCast(myListView.Columns(e.Column).Tag, System.Windows.Forms.SortOrder)
End If
If (prevColumnClick = e.Column) Then
If sort_order = SortOrder.Ascending Then
sort_order = SortOrder.Descending
Else
sort_order = SortOrder.Ascending
End If
End If
' Initialize ColumnSorter class
myListView.ListViewItemSorter = New ListViewColumnSorter(e.Column, sort_order, secondary_column_to_sort)
' Perform the sort with these new sort options.
'myListView.Sort()
' Store current column sorting order
myListView.Columns(e.Column).Tag = sort_order
' Store previous column number clicked
prevColumnClick = e.Column
End Sub
答案 3 :(得分:1)
这可能不是最有效的方式,但您可以执行以下操作:
listView.Sort(5); // Column F, then
listView.Sort(0); // Column A
请注意反向排序。
答案 4 :(得分:0)
这是在网上还是winform?在网络上,您可以将包含以逗号分隔的列和pass it to the sort() method of the listview
的表达式放在一起框架3.5及以上......
答案 5 :(得分:0)
好吧,如果您只想对列进行排序,请尝试使用List of List;例如如下:
List<List<string>> lstColumns = new List<List<string>>();
没有尝试过,只是想快速解决。