Suchen in BindingList

  • WPF
  • .NET (FX) 4.5–4.8

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

    Suchen in BindingList

    Ich habe eine BindingList und möchte darin nach einem Wert suchen und den Index zurückbekommen. Wie stelle ich das an?
    Klar, kann ich eine Schleife benutzen und jeden Datensatz durchgehen, bis ich einen passenden gefunden habe. Aber ich habe nach anderen Wegen gesucht, die eventuell etwas besser sind als eine Schleife. Wie z.B. die Funktion SingleOrDefault. Nur bin ich anscheinend zu blöd um die Hilfe richtig zu verstehen. Daher bin ich für Anregungen und Hilfestellung jeder Art dankbar.

    Beispiel:

    VB.NET-Quellcode

    1. Public Class BeispielKlasse
    2. Public Property Kontakte As New BindingList(Of BeispielKlasse.Kontakt)
    3. Public Function SearchForName(NameToSearch As String) As Int32
    4. '???????
    5. End Function
    6. Public Class Kontakt
    7. Public Property Name As String
    8. Public Property Vornmae As String
    9. Public Property Email As String
    10. End Class
    11. End Class
    Da eine BindingList(Of T) das IEnumerable(Of T)-Interface implementiert, sind von Haus aus die LINQ-Methoden wie SingleOrDefault verfügbar, siehe Anhang.

    VB.NET-Quellcode

    1. Public Function SearchForName(NameToSearch As String) As String
    2. Return Kontakte.SingleOrDefault(Function(x) x.Name = NameToSearch).Vornmae
    3. End Function

    Was da aber für ein Int32-Wert rauskommen soll, entzieht sich meiner Kenntnis. Daher habe ich das in dem Code und Screenshot angepasst.
    Bilder
    • Result.png

      34,6 kB, 1.346×269, 50 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Vielen Dank für die schnelle Antwort. Das funktioniert so super. Habe ich auch die Möglichkeit die Indexposition zu ermitteln?

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Module Module1
    3. Sub Main()
    4. Dim myKunden As New Kunden
    5. Console.WriteLine(myKunden.SearchForName("Nachname2").Vorname)
    6. Console.ReadLine()
    7. End Sub
    8. Public Class Kunden
    9. Public Property Kontakte As New BindingList(Of Kunden.Kontakt) From {New Kunden.Kontakt("Nachnname1", "Vorname1"), New Kunden.Kontakt("Nachname2", "Vorname2"), New Kunden.Kontakt("Nachname3", "Vorname3")}
    10. Public Function SearchForName(NameToSearch As String) As Kunden.Kontakt
    11. Return Kontakte.SingleOrDefault(Function(x) x.Name = NameToSearch)
    12. End Function
    13. Public Class Kontakt
    14. Public Property Name As String
    15. Public Property Vorname As String
    16. Sub New(NewName As String, NewVorname As String)
    17. Name = NewName
    18. Vorname = NewVorname
    19. End Sub
    20. End Class
    21. End Class
    22. End Module
    MAch eine Klasse die von BindingList<T> erbt, dann geht es weiter wie hier zu sehen:
    learn.microsoft.com/en-us/dotn…ydescriptor-system-object)
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

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

    Du kannst die Indexe der Einträge zunächst mit ausgeben. Dann filtern. (Wenn du nicht explizit überprüfen willst, dass das Element auch nur einmal drin ist, dann ist FirstOrDefault die richtige Wahl)

    VB.NET-Quellcode

    1. Dim test = Kontakte.Select(Function(k, i) New With {.kontakt = k, .idx = i}).FirstOrDefault(Function(kx) kx.Name = NameToSearch)
    2. Dim foundkontakt = test.kontakt
    3. Dim foundidx = test.idx
    Vielen Dank. Ich glaube, jetzt komme ich erstmal selber weiter. Hier mein kleiner TestCode:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Module Module1
    3. Sub Main()
    4. Dim myKunden As New Kunden
    5. Console.WriteLine(myKunden.SearchForName("Nachname2").Vorname)
    6. Console.WriteLine(myKunden.SearchForIndex("Nachname2"))
    7. Console.WriteLine(myKunden.SearchForIndex2("Nachname2"))
    8. Console.ReadLine()
    9. End Sub
    10. Public Class Kunden
    11. Public Property Kontakte As New BindingList(Of Kunden.Kontakt) From {New Kunden.Kontakt("Nachnname1", "Vorname1"), New Kunden.Kontakt("Nachname2", "Vorname2"), New Kunden.Kontakt("Nachname3", "Vorname3")}
    12. Public Function SearchForName(NameToSearch As String) As Kunden.Kontakt
    13. Return Kontakte.SingleOrDefault(Function(x) x.Name = NameToSearch)
    14. End Function
    15. Public Function SearchForIndex(NameToSearch As String) As Int32
    16. Dim i As Int32
    17. While i < Kontakte.Count
    18. If Kontakte(i).Name.ToLower = NameToSearch.ToLower Then
    19. Return i
    20. End If
    21. i += 1
    22. End While
    23. Return -1
    24. End Function
    25. Public Function SearchForIndex2(NameToSearch As String) As Int32
    26. Dim result = Kontakte.Select(Function(k, i) New With {.Kontakt = k, .idx = i}).SingleOrDefault(Function(x) x.Kontakt.Name = NameToSearch)
    27. Return result.idx
    28. End Function
    29. Public Class Kontakt
    30. Public Property Name As String
    31. Public Property Vorname As String
    32. Sub New(NewName As String, NewVorname As String)
    33. Name = NewName
    34. Vorname = NewVorname
    35. End Sub
    36. End Class
    37. End Class
    38. End Module
    Index-Suchen geben bei "nichts gefunden" immer -1 zurück - so ist die Konvention

    VB.NET-Quellcode

    1. Public Function SearchForIndex2(NameToSearch As String) As Int32
    2. Dim result = Kontakte.Select(Function(k, i) New With {.Kontakt = k, .idx = i}).SingleOrDefault(Function(x) x.Kontakt.Name = NameToSearch)
    3. Return If(result Is Nothing, -1, result.idx)
    4. End Function
    ausserdem wirft .SingleOrDefault() einen Fehler, wenn mehr als ein Treffer gefunden wird.
    Das kann erwünscht sein.
    Andernfalls nimm .FirstOrDefault()