我有一个datagridview,其中包含动态找到的设备的IP地址字符串列。
问题:我想比较这个IP地址字符串,以便我可以将它们排序为IP地址而不是字符串。我从stackflow问题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地址有什么好方法?或者可能以更优雅的方式进行自定义排序?
答案 0 :(得分: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
然后我将IP地址数组作为字符串,并使用它进行排序:
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())
这创建了一个包含有序地址的字符串数组。工作得很好!
答案 1 :(得分:0)
这是一个比较器类,用于在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地址位于第一列(更改为适合!)。