2014-07-25 5 views
1

J'ai un DataGridView avec une colonne de chaîne d'adresses IP de périphériques trouvés dynamiquement.VB.net: comparaison des adresses IP Chaînes à trier dans datagridview?

Problème: Je souhaite comparer cette chaîne d'adresses IP pour pouvoir les trier en tant qu'adresse IP et non en tant que chaîne. J'ai pris quelques conseils à partir des questions C#: Custom sort of DataGridView de stackflow et je vois que vous devez essentiellement trier la source de données d'origine, puis l'afficher dans la vue datagridview.

Ce que j'ai essayé:

J'ai essayé de créer une classe IComparer, mais je suis arrivé une exception InvalidOperation que ladite création d'un nouveau comparateur n'est pas bon car il est un objet lié aux données. Donc, c'est hors de question. Ce que je veux savoir, c'est un bon algorithme de chaîne pour refaire cela de manière à ce que 10.10.1.190 soit avant le 10.10.1.199. Mon premier réflexe était de supprimer le ".", De le multiplier et de faire un comparateur, mais cela ne fonctionne pas avec un grand nombre moyen (c'est-à-dire 10.10.0.197 contre 10.10.1.2).

J'ai également essayé de créer une liste d'Ipaddresses (analyse directe à partir des cellules de datagridview) mais la fonction list.sort() commet également une erreur.

Voici le code que j'ai l'intérieur de l'événement click d'en-tête (quand je le veux trier):

 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 

Qu'est-ce qu'un bon moyen de comparer les adresses IP? Ou peut-être faire le tri personnalisé d'une manière plus élégante?

+1

Cela peut être utile http://stackoverflow.com/questions/6248039/how-to-sort-list-of-ip-addresses-using-c-sharp – Steve

+0

Vous devrez peut-être utiliser un DataTable comme source pour votre DataGridView. De cette façon, vous pouvez utiliser la suggestion de Steve pour convertir la notation en pointillés IPv4 en UInt32 et trier dessus. Vous n'avez pas besoin d'afficher réellement la colonne avec la valeur UInt32. –

+0

Utiliser la vue de données. .. – Codexer

Répondre

2

Ceci est la solution que je fini par utiliser:

J'ai créé un 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 

Je fis alors un tableau des IPAddresses sous forme de chaînes, et triées à l'aide que:

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()) 

Cela a créé un tableau de chaînes avec les adresses dans l'ordre. Travaillé plutôt bien!

0

Permet de classer un type de tri par adresse IP dans un affichage de données.

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 

-vous la gérer comme d'habitude, i.e. dans un cliquez sur le bouton, il serait:

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. L'hypothèse dans la classe est que l'adresse IP est dans la première colonne (changer pour convenir!).