vb.net在ListView中排序混合的整数和字符串列 [英] vb.net sorting mixed integer and string column in ListView

查看:97
本文介绍了vb.net在ListView中排序混合的整数和字符串列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我(面对我)面对一个非常大的问题.我找不到任何解决方案.我的ListView中有四列:

I faced quiet a really big problem (for me). I cannot find any solution for it. I have four columns in my ListView:

ID = integer
Name = string
Response = boolean
Memory = mixed integer with string (1'000 KB)

在[ColumnClick]之后,我可以正常"对前3列进行排序(asc/desc),但是当我尝试对第4列进行排序时,而不是

After [ColumnClick] I can sort (asc/desc) first 3 columns "normally", but when i am trying to sort the fouth one, instead of

1 KB/5 KB/1'000 KB

我确实收到了这样的信息:

I do receive something like this:

1 KB/1'000 KB/5 KB

第四列是这样打印的:

ListView1.Items(Count).SubItems.Add(FormatNumber(pMem, 0) & " KB")

我正在考虑:

    If e.Column.ToString = 3 Then
        Dim final As Integer
        For Each value In ListView1.Items
            Replace(value.SubItems(3), "'", "")
            Replace(value.SubItems(3), " KB", "")
            final = value
        Next
    Else
    ...

然后使用与ID相同的方式对整数进行排序,然后以某种方式将它们放回ListView.但是我不知道怎么办.

Then sort integers same way as ID was, and then put them back, to the ListView somehow. But I cannot figure out how.

用于在表单中排序:

Private Sub ListView1_ColumnClick(sender As Object, e As ColumnClickEventArgs) Handles ListView1.ColumnClick
    Dim ListViewSorter As New ListViewSorter

    With ListViewSorter
        .SortingOrder = 1
        .ColumnIndex = e.Column
    End With

    ListView1.ListViewItemSorter = ListViewSorter
End Sub

还有我的ListViewSorter.vb

And my ListViewSorter.vb

Public Class ListViewSorter
Implements IComparer

Private ColumnId As Integer
Private SortOrder As SortOrder
Private ItemComparer As CaseInsensitiveComparer

Public Sub New()
    ColumnId = 0
    SortOrder = 0
    ItemComparer = New CaseInsensitiveComparer()
End Sub

Public Property ColumnIndex() As Integer
    Get
        Return ColumnId
    End Get
    Set(Value As Integer)
        ColumnId = Value
    End Set
End Property

Public Property SortingOrder() As SortOrder
    Get
        Return SortOrder
    End Get
    Set(Value As SortOrder)
        SortOrder = Value
    End Set
End Property

Public Function Compare(x As Object, y As Object) As Integer Implements IComparer.Compare
    Dim myResults As Integer
    Dim strX As String = DirectCast(x, ListViewItem).SubItems(ColumnId).Text
    Dim strY As String = DirectCast(y, ListViewItem).SubItems(ColumnId).Text
    Dim num As Point

    If Integer.TryParse(strX, num.X) And Integer.TryParse(strY, num.Y) Then
        myResults = ItemComparer.Compare(num.X, num.Y)
    Else
        myResults = ItemComparer.Compare(strX, strY)
    End If

    If SortOrder = 1 Then
        Return myResults
    ElseIf SortOrder = 2 Then
        Return -myResults
    Else
        Return 0
    End If
End Function
End Class

推荐答案

最佳解决方案是使用DataGridView.使用DataSource,而不是先创建和添加ListViewItems,然后再添加ListViewSubItems,您可以用一行代码填充控件.它还使用类型化的列,因此KB或KG的列将像数字一样排序.然后可以使用简单的linq表达式对DataSource重新排序.

The optimum solution would be to use a DataGridView. Using a DataSource, rather than creating and adding ListViewItems, then ListViewSubItems, you could populate the control with one line of code. It also uses typed columns, so a column of KBs or KGs would sort like numbers. A simple linq expression could then be used to reorder the DataSource.

值得考虑的是,在ColumnHeader中添加"KB"标识,这样它就不会在文本中一遍又一遍地重复,并且必须被剥离以进行排序.

It would be worth considering adding the "KB" designation in the ColumnHeader so it doesn't repeat over and over in the text and have to be stripped off for sorting.

由于ListView仅存储文本,因此您可能会遇到其他问题:"9 KB"的排序要比"1000 KB"高,因为那里没有整数-它们是数字.在许多情况下,可以对包含数字的字符串使用NaturalSort(就像资源管理器"一样),但是由于某种原因,它不喜欢'数字组分隔符.

Since the ListView stores only text, you can have other issues: "9 KB" will sort higher than "1000 KB" because there are no integers there - they are numerals. In many cases, you can use a NaturalSort for strings containing numerals ("just like explorer"), but for whatever reason it didn't like the ' number group separator.

留下ListViewItemSorter给我们.您可能已经有一个用于对第1列和第2列进行排序.还需要更多逻辑才能从KB列中提取实际数值进行排序:

Which leaves us with a ListViewItemSorter. You probably already have one for sorting column 1 and 2. A little more logic is needed to extract an actual numeric value from the KB column for sorting:

Public Class ListViewKBItemComparer
    Implements IComparer
    Private mySortFlipper As Int32 = 1
    Public Property SortColumn As Int32 = 0

    Public Sub New()

    End Sub

    Public Sub New(column As Int32, sort As SortOrder)
        mySortFlipper = If(sort = SortOrder.Ascending, 1, -1)
        SortColumn = column
    End Sub

    Public Function Compare(x As Object, y As Object) As Integer Implements IComparer.Compare
        Dim result As Int32
        Dim lvX = CType(x, ListViewItem)
        Dim lvY = CType(y, ListViewItem)

        If SortColumn = 3 Then
            result = KBCompare(lvX, lvY)
        Else
            result = String.Compare(lvX.SubItems(SortColumn).Text,
                                    lvY.SubItems(SortColumn).Text)
        End If

        Return (result * mySortFlipper)
    End Function


    Private Function KBCompare(x As ListViewItem, y As ListViewItem) As Int32
        ' strip the text
        Dim xs = x.SubItems(SortColumn).Text.Replace(" KB", "")
        Dim ys = y.SubItems(SortColumn).Text.Replace(" KB", "")

        ' convert to decimal
        Dim decX As Decimal = -1
        Decimal.TryParse(xs, decX)

        Dim decY As Decimal = -1
        Decimal.TryParse(ys, decY)
        ' return comparison result
        Return decX.CompareTo(decY)

    End Function
End Class

在某些字符串也可能包含小数的情况下,我使用了Decimal.如果不是,只需将Decimal更改为Int32.

I used Decimal in case some of the strings could also include fractions. If not, just change Decimal to Int32.

用法:

myLV.ListViewItemSorter = New ListViewKBItemComparer(e.Column, SortAsc)
myLV.Sort()

e.ColumnColumnClick事件的参数; SortAscSortOrder表示升序或降序.

e.Column is a param from the ColumnClick event; and SortAsc is a SortOrder to indicate Asc or Desc.

这篇关于vb.net在ListView中排序混合的整数和字符串列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆