【问题标题】:VB.net: Comparing IP Addresses Strings for sorting in datagridview?VB.net:比较 IP 地址字符串以在 datagridview 中进行排序?
【发布时间】:2014-09-17 18:56:56
【问题描述】:

我有一个数据网格视图,其中包含动态找到的设备 IP 地址的字符串列。

问题:我想比较这个 IP 地址字符串,以便我可以将它们作为 IP 地址而不是字符串进行排序。我从堆栈流问题C#: Custom sort of DataGridView 中得到了一些提示,发现您基本上必须对原始数据源进行排序,然后将其显示在 datagridview 上。

我尝试过的:

我尝试创建一个 IComparer 类,但我得到一个 InvalidOperation 异常,说创建一个新的比较器不好,因为它是一个数据绑定对象。所以,这是不可能的。我想知道的是一个很好的字符串算法,基本上可以重做这个,以便 10.10.1.190 在 10.10.1.199 之前。

我的第一个想法是删除“.”,乘以并进行数字比较,但这不适用于较大的中间数字(即 10.10.0.197 与 10.10.1.2)。

我还尝试创建 Ipaddresses 列表(从 datagridview 的单元格直接解析),但 list.sort() 函数也会出错。

这是我在标题点击事件中的代码(当我希望它排序时):

      If selectedColumn.Name = "IP Address" Then
         'gives error, invalidOperation
       'cameraTable is the datagridview name
       '   cameraTable.Sort(New CellComparer(SortOrder.Ascending))

            For i As Integer = 0 To cameraTable.Rows.Count - 1
                unsortedCopy.Add(Net.IPAddress.Parse(cameraTable("IP Address", i).Value.ToString))

           Next

           'gives error
            unsortedCopy.Sort()

        'make new datatable with sorting matching array 
        'make it datasource
        'refresh GUI

        End If

比较 IP 地址的好方法是什么?或者可能以更优雅的方式进行自定义排序?

【问题讨论】:

  • 这可能会有所帮助stackoverflow.com/questions/6248039/…
  • 您可能需要使用 DataTable 作为 DataGridView 的源。这样,您可以使用 Steve 的建议将 IPv4 点表示法转换为 UInt32 并对其进行排序。您不必实际显示具有 UInt32 值的列。
  • 我将代码更改为复制列并将其放入 String() 的数组中,该数组由“.”分割。我将尝试看看 vb.net 是否会让我遵循 steve 的建议。
  • 我正在尝试这一行。关于如何修复 vb.net 抱怨“Version.Parse”的任何提示? Dim sortedIps = unsortedIps.[Select](Version.Parse).OrderBy(Function(arg) arg).[Select](Function(arg) arg.ToString()).ToList()

标签: vb.net sorting datagridview ip-address


【解决方案1】:

这是一个比较器类,用于在 datagridview 中按 IP 地址排序。

Public Class RowComparer
    Implements System.Collections.IComparer
    Private sortOrderModifier As Integer = 1

    Public Sub New(ByVal sortOrder As SortOrder)
        If sortOrder = sortOrder.Descending Then
            sortOrderModifier = -1
        ElseIf sortOrder = sortOrder.Ascending Then
            sortOrderModifier = 1
        End If
    End Sub

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

        Dim first As Byte() = IPAddress.Parse(CType(x, DataGridViewRow).Cells(0).Value.ToString()).GetAddressBytes()
        Dim second As Byte() = IPAddress.Parse(CType(y, DataGridViewRow).Cells(0).Value.ToString()).GetAddressBytes()

        'first part of the IP Address
        Dim ipCompare As Integer = If(CInt(first(0)) > CInt(second(0)), 1, If(CInt(first(0)) < CInt(second(0)), -1, 0))
        'second part of the IP Address
        If ipCompare = 0 Then
            ipCompare = If(CInt(first(1)) > CInt(second(1)), 1, If(CInt(first(1)) < CInt(second(1)), -1, 0))
        End If
        'third part of the IP Address
        If ipCompare = 0 Then
            ipCompare = If(CInt(first(2)) > CInt(second(2)), 1, If(CInt(first(2)) < CInt(second(2)), -1, 0))
        End If
        'fourth part of the IP Address
        If ipCompare = 0 Then
            ipCompare = If(CInt(first(3)) > CInt(second(3)), 1, If(CInt(first(3)) < CInt(second(3)), -1, 0))
        End If
        Return ipCompare * sortOrderModifier

    End Function
End Class

您像往常一样处理它,即在一个按钮内单击它会是:

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles Button1.Click
    If RadioButton1.Checked = True Then
        DataGridView1.Sort(New RowComparer(SortOrder.Ascending))
    ElseIf RadioButton2.Checked = True Then
        DataGridView1.Sort(New RowComparer(SortOrder.Descending))
    End If 
End Sub

PS。类中的假设是 IP 地址在第一列(更改以适应!)。

【讨论】:

    【解决方案2】:

    这是我最终使用的解决方案:

    我创建了一个 Icomparer:

    Class IPAddressComparer
    Implements IComparer(Of Net.IPAddress)
    
    
    Public Function Compare1(x As Net.IPAddress, y As Net.IPAddress) As Integer Implements IComparer(Of Net.IPAddress).Compare
        Dim first As Byte() = x.GetAddressBytes()
        Dim second As Byte() = y.GetAddressBytes()
        Return first.Zip(second, Function(a, b) a.CompareTo(b)).FirstOrDefault(Function(c) c <> 0)
    End Function
    End Class
    

    然后我将 IPAddresses 数组作为字符串,并使用它进行排序:

      Dim unsortedCopy As New List(Of String)
    
                For i As Integer = 0 To cameraTable.Rows.Count - 1
                    unsortedCopy.Add(cameraTable(selectedColumn.Name, i).Value.ToString)
                Next
    
                Dim sorted = unsortedCopy.OrderBy(Function(s) Net.IPAddress.Parse(s), New IPAddressComparer())
    

    这创建了一个按顺序排列地址的字符串数组。工作得很好!

    【讨论】:

      猜你喜欢
      • 2021-08-30
      • 1970-01-01
      • 2015-05-17
      • 2012-04-29
      • 1970-01-01
      • 2012-02-08
      • 2011-10-02
      • 2016-03-04
      • 1970-01-01
      相关资源
      最近更新 更多