Listview Column sortieren mit Beachtung des Vorzeichens

  • VB.NET

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Listview Column sortieren mit Beachtung des Vorzeichens

    Hallo!

    Hab iwie das ganze Netz schon durchsucht, finde aber immer nur String-Basierte sortieralgos..und keins berücksichtigt die vermeindlichen Vorzeichen von Double-Werten!

    Hat vllt jemand ne Quelle für eine Sortier-Implementierung für Listviews die Vorzeichen wie plus und minus berücksichtigen?!?

    Das ist das was ich gefunden habe:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim blnAscending As Boolean = True
    2. Private Sub lvBTC_ColumnClick(sender As Object, e As ColumnClickEventArgs) Handles lvBTC.ColumnClick
    3. Dim _listView As ListView = DirectCast(sender, ListView)
    4. _listView.ListViewItemSorter = New ListViewItemComparer(e.Column, blnAscending)
    5. blnAscending = Not blnAscending
    6. End Sub
    7. ' Implements the manual sorting of items by columns.
    8. Class ListViewItemComparer
    9. Implements IComparer
    10. Private col As Integer
    11. Private AscOrder As Boolean
    12. Public Sub New()
    13. col = 0
    14. AscOrder = True
    15. End Sub
    16. Public Sub New(ByVal column As Integer, ByVal Ascending As Boolean)
    17. col = column
    18. AscOrder = Ascending
    19. End Sub
    20. Dim _stringX As String = Nothing
    21. Dim _stringY As String = Nothing
    22. Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
    23. If AscOrder Then
    24. _stringX = CType(x, ListViewItem).SubItems(col).Text
    25. _stringY = CType(y, ListViewItem).SubItems(col).Text
    26. Return [String].Compare(_stringX, _stringY)
    27. Else
    28. _stringX = CType(x, ListViewItem).SubItems(col).Text
    29. _stringY = CType(y, ListViewItem).SubItems(col).Text
    30. Return [String].Compare(_stringY, _stringX)
    31. End If
    32. End Function
    33. End Class


    Im DataGridView klappt die Sortierung wunderbar! :/

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Morrison“ ()

    @Morrison So was:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    3. ' configure Listview
    4. ListView1.View = View.Details
    5. ListView1.Columns.Add(New ColumnHeader())
    6. Me.ListView1.Columns(0).Text = "Column 0"
    7. ListView1.Columns.Add(New ColumnHeader())
    8. Me.ListView1.Columns(1).Text = "Column 1"
    9. ListView1.Columns.Add(New ColumnHeader())
    10. Me.ListView1.Columns(2).Text = "Column 2"
    11. ' SET SORT
    12. ListView1.Sorting = SortOrder.Ascending
    13. ' add some values
    14. ListView1.Items.Add(New ListViewItem(New String() {"9", "A", "e"}))
    15. ListView1.Items.Add(New ListViewItem(New String() {"1", "b", "D"}))
    16. ListView1.Items.Add(New ListViewItem(New String() {"-1", "C", "c"}))
    17. ListView1.Items.Add(New ListViewItem(New String() {"-5", "d", "B"}))
    18. ListView1.Items.Add(New ListViewItem(New String() {"100", "E", "a"}))
    19. End Sub
    20. Private Sub ListView1_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView1.ColumnClick
    21. Select Case e.Column
    22. Case 0
    23. Me.ListView1.ListViewItemSorter = New ListViewItemComparer123(0)
    24. Case Else
    25. Me.ListView1.ListViewItemSorter = New ListViewItemComparerABC(e.Column)
    26. End Select
    27. End Sub
    28. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    29. Dim txt = ListView1.FocusedItem.Text
    30. End Sub
    31. End Class
    32. ' LV Sorter: sorts 1.column numeric
    33. Class ListViewItemComparer123
    34. Implements IComparer
    35. Private col As Integer
    36. Public Sub New()
    37. col = 0
    38. End Sub
    39. Public Sub New(ByVal column As Integer)
    40. col = column
    41. End Sub
    42. Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
    43. Dim lviX As ListViewItem = CType(x, ListViewItem)
    44. Dim lviY As ListViewItem = CType(y, ListViewItem)
    45. ' compare number in 1. Column
    46. Return CInt(lviX.Text) - CInt(lviY.Text)
    47. End Function
    48. End Class
    49. ' Implements the manual sorting of items by columns.
    50. Class ListViewItemComparerABC
    51. Implements IComparer
    52. Private col As Integer
    53. Public Sub New()
    54. col = 0
    55. End Sub
    56. Public Sub New(ByVal column As Integer)
    57. col = column
    58. End Sub
    59. Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
    60. Implements IComparer.Compare
    61. Return [String].Compare(CType(x, ListViewItem).SubItems(col).Text, CType(y, ListViewItem).SubItems(col).Text)
    62. End Function
    63. End Class

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Guten Morgen @Morrison

    Hast du die Möglichkeit den Datentyp in das Tag-Property des ColumnHeader zu schreiben.
    Z.B. System.Double.

    Man könnte auch den Datentyp Codetechnische reinschreiben.

    Hier mein IComparer für das Sortieren einer ListView-Column. Der geht auch für Double.

    ListView nach Spalten sortieren

    Beispiel von RFG

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Public Class Form1
    4. Private colIndex As Int32 = -1
    5. Private sortord As SortOrder = SortOrder.Ascending
    6. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    7. ' configure Listview
    8. Me.ListView1.View = View.Details
    9. Me.ListView1.Columns.Add(New ColumnHeader() With {.Tag = GetType(Int32)})
    10. Me.ListView1.Columns(0).Text = "Column 0"
    11. ListView1.Columns.Add(New ColumnHeader() With {.Tag = GetType(String)})
    12. Me.ListView1.Columns(1).Text = "Column 1"
    13. Me.ListView1.Columns.Add(New ColumnHeader() With {.Tag = GetType(String)})
    14. Me.ListView1.Columns(2).Text = "Column 2"
    15. Me.ListView1.Columns.Add(New ColumnHeader() With {.Tag = GetType(Double)})
    16. Me.ListView1.Columns(3).Text = "Column 3"
    17. ' add some values
    18. Me.ListView1.Items.Add(New ListViewItem(New String() {"9", "A", "e", "3.02"}))
    19. Me.ListView1.Items.Add(New ListViewItem(New String() {"1", "b", "D", "-7.65"}))
    20. Me.ListView1.Items.Add(New ListViewItem(New String() {"-1", "C", "c", "-2.87"}))
    21. Me.ListView1.Items.Add(New ListViewItem(New String() {"-5", "d", "B", "8.09"}))
    22. Me.ListView1.Items.Add(New ListViewItem(New String() {"100", "E", "a", "-1.99"}))
    23. End Sub
    24. Private Sub ListView1_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView1.ColumnClick
    25. Me.ColumnSort(e.Column)
    26. End Sub
    27. Private Sub ColumnSort(ByVal columnindex As Int32)
    28. Dim idx As Int32 = columnindex
    29. If Not idx = colIndex Then
    30. colIndex = idx
    31. sortord = SortOrder.Descending
    32. End If
    33. 'Sortierung umkehren
    34. If Not sortord = SortOrder.Ascending Then
    35. sortord = SortOrder.Ascending
    36. Else : sortord = SortOrder.Descending
    37. End If
    38. Dim typ As Type = Me.GetColumnType(idx)
    39. Me.ListView1.ListViewItemSorter = New ListViewItemComparer(idx, typ, sortord)
    40. End Sub
    41. Private Function GetColumnType(ByVal idx As Int32) As Type
    42. 'Den Type per Designer (oder per Code) in das Tag-Property des ColumnHeader
    43. 'schreiben, dann kann man so drauf greifen.
    44. Return DirectCast(Me.ListView1.Columns(idx).Tag, Type)
    45. End Function
    46. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    47. Dim txt = ListView1.FocusedItem.Text
    48. End Sub
    49. End Class


    ListViewItemComparer

    VB.NET-Quellcode

    1. Public Class ListViewItemComparer
    2. Implements IComparer
    3. Private sorttype As Type, index As Int32, sortord As SortOrder
    4. Public Function Compare(ByVal x As Object, ByVal y As Object) As Int32 Implements IComparer.Compare
    5. If GetType(String) = Me.sorttype Then
    6. If Me.sortord = SortOrder.Ascending Then
    7. Return [String].Compare(CType(x, ListViewItem).SubItems(Me.index).Text, CType(y, ListViewItem).SubItems(Me.index).Text)
    8. Else : Return [String].Compare(CType(y, ListViewItem).SubItems(Me.index).Text, CType(x, ListViewItem).SubItems(Me.index).Text)
    9. End If
    10. End If
    11. If GetType(Decimal) = Me.sorttype Then
    12. If Me.sortord = SortOrder.Ascending Then
    13. Return Decimal.Compare(CDec(CType(x, ListViewItem).SubItems(Me.index).Text), CDec(CType(y, ListViewItem).SubItems(Me.index).Text))
    14. Else : Return Decimal.Compare(CDec(CType(y, ListViewItem).SubItems(Me.index).Text), CDec(CType(x, ListViewItem).SubItems(Me.index).Text))
    15. End If
    16. End If
    17. If GetType(Date) = Me.sorttype Then
    18. If Me.sortord = SortOrder.Ascending Then
    19. Return Date.Compare(CDate(CType(x, ListViewItem).SubItems(Me.index).Text), CDate(CType(y, ListViewItem).SubItems(Me.index).Text))
    20. Else : Return Date.Compare(CDate(CType(y, ListViewItem).SubItems(Me.index).Text), CDate(CType(x, ListViewItem).SubItems(Me.index).Text))
    21. End If
    22. End If
    23. Return -1
    24. End Function
    25. Private Function IsNumericType(ByVal typ As Type) As Boolean
    26. If typ Is Nothing Then Return False
    27. Select Case Type.GetTypeCode(typ)
    28. Case TypeCode.Byte, TypeCode.Decimal, TypeCode.Double, TypeCode.Int16, TypeCode.Int32, TypeCode.Int64, _
    29. TypeCode.SByte, TypeCode.Single, TypeCode.UInt16, TypeCode.UInt32, TypeCode.UInt64
    30. Return True
    31. Case TypeCode.Object
    32. If typ.IsGenericType AndAlso typ.GetGenericTypeDefinition() = GetType(Nullable(Of )) Then
    33. Return IsNumericType(Nullable.GetUnderlyingType(typ))
    34. End If
    35. Return False
    36. End Select
    37. Return False
    38. End Function
    39. Public Sub New(ByVal idx As Int32, ByVal typ As Type, ByVal sortorde As SortOrder)
    40. Me.index = idx : Me.sorttype = typ : Me.sortord = sortorde
    41. If IsNumericType(typ) Then
    42. Me.sorttype = GetType(Decimal)
    43. End If
    44. End Sub
    45. End Class

    Freundliche Grüsse

    exc-jdbi

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „exc-jdbi“ ()