Combobox auswahl filter

  • VB.NET
  • .NET (FX) 4.0

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

    Combobox auswahl filter

    Guten Morgen liebe VBP-Com,

    ich habe aktuell folgendes problem:

    ich habe eine Combobox mit werten gefüllt(strings), nun will ich aber dass wenn man im combobox feld was eingibt, und dann alles was mit der eingabe anfängt rausfilter und als auswahl setzt. Sobald die eingabe gelöscht wird sollen wieder alle werte angezeigt werden.

    Hier mal der Vorgehende code:

    VB.NET-Quellcode

    1. Private _Directories As New List(Of String)
    2. Private _Drives As DriveInfo()
    3. Private _Filter As New List(Of String)
    4. Private Sub dlgDirectorySelect_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    5. _Drives = DriveInfo.GetDrives.Where(Function(dri) dri.IsReady).ToArray
    6. For Each dri In _Drives
    7. For Each di In dri.RootDirectory.EnumerateDirectories
    8. If AcceptDir(di, "$R", "Boot") Then _Directories.Add(di.FullName)
    9. Next
    10. Next
    11. cb_output.DataSource = _Directories
    12. End Sub
    13. Private Function AcceptDir(di As DirectoryInfo, ParamArray rejectPatterns() As String) As Boolean
    14. For Each pat In rejectPatterns
    15. If _Drives.Any(Function(dri) di.FullName.StartsWith(dri.RootDirectory.FullName & pat)) Then Return False
    16. Next
    17. Return True
    18. End Function


    und hier mein aktueller ansatz der nicht so klappt da er mir wenn ich die item clearen will immer ne exeption schmeißt, darum mal ohne clealer:

    VB.NET-Quellcode

    1. Private Sub cb_output_TextChanged(sender As Object, e As EventArgs) Handles cb_output.TextChanged
    2. Dim filter As String
    3. filter = cb_output.Text
    4. For i As Integer = 0 To _Directories.Count - 1
    5. If _Directories(i).StartsWith(filter) Then
    6. _Filter.Add(_Directories(i))
    7. End If
    8. Next
    9. cb_output.DataSource = _Filter
    10. End Sub


    ich hoffe wir können zusammen einen ansatz finden, der mein problem lösen wird.

    LG
    LC
    Diese Herangehensweise ist für eine

    Lord C schrieb:

    Combobox
    nicht unbedingt sinnvoll, dafür ist die ComboBox eigentlich nicht gemacht.
    Mach Dir eine von ComboBox abgeleitete Klasse und merk Dir die Ur-Items.
    Leider gibt es kein Item-Change-Event.
    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!

    Lord C schrieb:

    dann lass ichs lieber
    Warum?
    Probier dies:

    WhitePage schrieb:

    Bindingsource
    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!
    Es geht über BindingSource doch nicht, dafür aber noch einfacher:

    VB.NET-Quellcode

    1. ComboBox1.DataSource=MyList
    2. Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.TextChanged
    3. Dim txt = ComboBox1.Text
    4. ComboBox1.DataSource = Nothing
    5. ComboBox1.DataSource = MyList.FindAll(Function(x) x.Contains(txt))
    6. End Sub

    ja, was dir vorschwebt, ist einfach so nicht vorgesehen:
    Einerseits hast du eine vorgegebene Liste, und nur diese Item können ausgewählt werden. Das ist Job einer datengebundenen Combobox wie die von WhitePage.
    Andererseits willst du freien Text hineinschreiben können. Das ist Job einer daten-ungebundenen Textbox.

    Man kann auch Textboxen mit AutoCompletion-Verhalten ausstatten, in etwa wie die Address-Eingabe eines Browsers, wo bei Eingabe iwelche Vorschläge combobox-artig droppen.
    Das ist aber keine Combobox, und das Problem ist grade die freie Texteingabe.
    Denn freie Texteingabe ist bei dir letztendlich ja gar nicht zulässig, denn es geht ja nicht an, dass du Directories reinschreiben kannst, die nicht existieren.
    @LordC: ja, wie gesagt: Das Problem ist dann, dass der User Schwachfug eingeben kann.

    Vorschlag: Schreib du ein Form, was im Hintergrund die zulässigen Strings enthält - haste ja eiglich schon, nämlich dlgDirectorySelect mit den _Directories.

    Nun code eine Textbox, in die man frei hineinschreiben kann, und wenn was sinnvolles drinne steht, wird ein Index gesetzt, mit dem das entsprechende Directory in _Directories andressierbar ist.
    Und - das ist das schwierige - code auch etwas, wenn Unfug eingegeben wurde - wie soll es dann weitergehen?
    ZB könntest du in diesen Fällen den Ok-Button (wenn es einen gibt) disablen.

    Also code du sowas, zippen, anhängen, und ich mach dann das rausploppen dran.

    @WhitePage: Und ist der DropDown dabei auch geöffnet, dass man die Auswahl sieht?
    Dann ginge das ja vlt. auch.
    Kommentiers aus :D ist nicht so wichtig der code läuft auch ohne

    Edit:

    VB.NET-Quellcode

    1. If Not IO.Directory.Exists("C:\Program Files\Save_Path\") Then
    2. IO.Directory.CreateDirectory("C:\Program Files\Save_Path\")
    3. Else
    4. If Not IO.File.Exists("C:\Program Files\Save_Path\other_diretory.txt") Then
    5. IO.File.Create("C:\Program Files\Save_Path\other_diretory.txt")
    6. End If
    7. End If
    8. source_change_q = True


    den Teil meine ich mit auskommentieren
    Jo - also bei mir funzt dieses grad ganz gut:

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class dlgDirectorySelect
    3. Private _Directories As New List(Of String)
    4. Private _Drives As DriveInfo()
    5. Private _AutoCompleteSource As New AutoCompleteStringCollection
    6. Private Sub dlgDirectorySelect_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    7. _Drives = DriveInfo.GetDrives.Where(Function(dri) dri.IsReady).ToArray
    8. For Each dri In _Drives
    9. For Each di In dri.RootDirectory.EnumerateDirectories
    10. If AcceptDir(di, "$R", "Boot") Then _Directories.Add(di.FullName)
    11. Next
    12. Next
    13. _AutoCompleteSource.AddRange(_Directories.ToArray)
    14. tb_pfadSelect.AutoCompleteCustomSource = _AutoCompleteSource
    15. End Sub
    16. '...
    17. Private Sub tb_pfadSelect_TextChanged(sender As Object, e As EventArgs) Handles tb_pfadSelect.TextChanged
    18. Dim eingabe = tb_pfadSelect.Text
    19. Dim _Filter As Integer = 0
    20. Dim _butSelect As Boolean = True
    21. For i As Integer = 0 To _Directories.Count - 1
    22. If _Directories(i).StartsWith(eingabe, StringComparison.OrdinalIgnoreCase) Then 'kl Verbesserung
    23. _Filter = i
    24. Exit For
    25. Else
    26. _Filter = -1
    27. End If
    28. Next
    29. If _Filter = -1 Then
    30. _butSelect = False
    31. Else
    32. _butSelect = True
    33. End If
    34. but_accept.Enabled = _butSelect
    35. End Sub
    36. '...
    Du musst noch im Designer tb_pfadSelect.AutoCompletionMode.SuggestAppend und tb_pfadSelect.AutoCompletionSource.CustomSource einstellen.

    Und dann empfehle ich ja immer, den "Deppen-Namespace" rauszuwerfen - man braucht ihn wirklich nicht: Visual Studio - Empfohlene Einstellungen

    Ach - nochne Verbesserung:

    VB.NET-Quellcode

    1. Private Sub tb_pfadSelect_TextChanged(sender As Object, e As EventArgs) Handles tb_pfadSelect.TextChanged
    2. Dim eingabe = tb_pfadSelect.Text
    3. but_accept.Enabled = _Directories.Any(Function(s) s.StartsWith(eingabe, StringComparison.OrdinalIgnoreCase))
    4. End Sub

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