Checked Listbox Problem mit CheckedItems

  • VB.NET

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von Olderman.

    Checked Listbox Problem mit CheckedItems

    Hallo,
    ich komme mit einem wahrscheinlich banalen Problem einfach nicht weiter und hoffe auf Eure Hilfe:
    Ich setze eine Checked-Listbox ein um mehrere Optionen aus- oder abzuwählen. Unmittelbar nach jeder Änderung sollen über eine Function andere Auflistungen angepasst werden.
    Beim Aufruf dieser Funktion über .ItemCheck ist die Auflistung CheckedItems noch nicht aktualisiert sondern entspricht dem Zustand vor dem Ändern des Items und somit füllt die damit aufgerufene Function die Listen entsprechend einer Auswahl welcher nicht der angezeigten Auswahl in der Checked-Listbox entspricht.
    Bei .SelectedIndexChanged ist zwar die Auflistung aktuell aber wenn man den .SelectIndex nicht ändert und der Checkedzustand des gerade geänderten Item wieder neu an-oder abwählt wird, wird .SelectedIndexChanged und damit meine Function die die anderen Listen anpasst nicht aufgerufen.
    Wenn ich nun bei .SelectedIndexChanged noch ein .Selecteditem = -1 einfüge funktioniert das Ganze wie gewünscht aber nur so lange wie man nicht zu schnell clickt. Bei einem Doppelclick ändert sich die Anzeige 2x mal also der alte Anzeigezustand wird wieder hergestellt, aber die .SelectedIndexChanged wird nur einmal aufgerufen. Dadurch wird meine Function nur einmal "zwischen den beiden" Clicks aufgerufen und wieder entsprechen meine Auflistungen nicht der angezeigten Auswahl.
    Versuche mit .Click / .MouseUp und Refresh-Aufruf führten alle nicht zum Erfolg.
    Ich möchte natürlich gewährleisten, das die angezeigten Ergebnisse in jedem Fall der angezeigten Auswahl in der Checked-Listbox entsprechen.
    Wahrscheinlich ist dieses ganz einfach - aber ich verzweifle langsam.
    Ich hoffe, ich konnte mein Problem einigermaßen verständlich machen.


    Vielen Dank im Voraus

    Olderman schrieb:

    Wahrscheinlich ist dieses ganz einfach - aber ich verzweifle langsam.
    Zurecht. Die CLB gibt es einfach nicht her, was Du willst. Man muss sich leider mit Tricks behelfen, zu finden z.B. bei stackoverflow. Du bist beim ItemCheck-Event(Handler) schon richtig. Es muss leider folgendermaßen abgewandelt werden:

    VB.NET-Quellcode

    1. Private Sub CheckedListBox1_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
    2. Me.BeginInvoke(Sub() MessageBox.Show(CheckedListBox1.CheckedItems.Count.ToString))
    3. End Sub
    Oder statt der MessageBox Deine eigene Funktionalität. Falls mehrzeilig, dann:

    VB.NET-Quellcode

    1. Private Sub CheckedListBox1_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
    2. Me.BeginInvoke(Sub()
    3. MessageBox.Show(CheckedListBox1.CheckedItems.Count.ToString)
    4. Prozedur1DieDuAufrufenWillst()
    5. Dim Ergebnis = Function2DieDuAufrufenWillst()
    6. 'blablabla
    7. End Sub)
    8. End Sub
    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.
    Ein anderer Ansatz ist, dass man erkennt, falls man es nicht weiß, dass in eine CheckedListBox durchaus komplexe Typen aufnehmen kann. Zweitens sollte man die CheckOnClick-Property auf True stellen. Drittens, wie schon von @VaporiZed gesagt, das ItemCheck-Event nutzen.

    Zu erstens:

    VB.NET-Quellcode

    1. Public Class Item
    2. Public Property SubToRun As Action
    3. Public Property Description As String
    4. Public Sub New(subToRun As Action, description As String)
    5. Me.SubToRun = subToRun
    6. Me.Description = description
    7. End Sub
    8. Public Overrides Function ToString() As String
    9. Return Me.Description
    10. End Function
    11. End Class


    Das könnte ein Item in der CheckListBox darstellen. Wie man sehen kann enthält diese Klasse eine Property SubToRun. Hier wird der Verweis auf jene Prozedur angegeben, die bei Bedarf aufgerufen werden soll. Außerdem wird die ToString-Methode der Basisklasse (Object) überschrieben. Der zurückgegebene Wert dieser Funktion entspricht dem, was als Eintrag in der CheckListBox erscheint.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Me.CheckedListBox1.Items.Add(New Item(AddressOf Sub1, "Task1"))
    4. Me.CheckedListBox1.Items.Add(New Item(AddressOf Sub2, "Task2"))
    5. Me.CheckedListBox1.Items.Add(New Item(AddressOf Sub3, "Task3"))
    6. Me.CheckedListBox1.Items.Add(New Item(Sub() MessageBox.Show("Anonymous Sub"), "Task4"))
    7. AddHandler Me.CheckedListBox1.ItemCheck, AddressOf CheckedListBox1_ItemCheck
    8. End Sub
    9. Private Sub CheckedListBox1_ItemCheck(sender As Object, e As ItemCheckEventArgs)
    10. Dim i As Item = DirectCast(Me.CheckedListBox1.Items(e.Index), Item)
    11. If e.NewValue = CheckState.Checked Then
    12. i.SubToRun.Invoke()
    13. End If
    14. End Sub
    15. Private Sub Sub1()
    16. Debug.Print("Sub1")
    17. End Sub
    18. Private Sub Sub2()
    19. Debug.Print("Sub2")
    20. End Sub
    21. Private Sub Sub3()
    22. Debug.Print("Sub3")
    23. End Sub
    24. End Class


    Hier werden 4 Einträge erzeugt. 3 rufen "normale" Prozeduren auf und die letzte eine Anonyme. Wobei man erwähnen muss, dass man hier nicht auf parameterlose Subs beschränkt ist. Man ändert eben die Signatur entsprechend. Auch Funktionen sind kein Problem. Function statt Action, Action(Of String, String, String), Function(Of Integer, String, String) usw.

    Im Eventhandler wird nun das gerade geclickte Item ermittelt. e gibt einem hier den Hinweis. Weiterhin sagt dir e, wie der neue Zustand des Items ist. Hier kannst Du Dich einhängen und machen, was immer Du möchtest und der Zustand entspricht immer dem Datenbestand.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o