[Beispielprojekt] Listbox erweitern

    • VB.NET

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

      [Beispielprojekt] Listbox erweitern

      Hallo alle zusammen^^
      In diesem Beitrag will ich euch ein kleines Beispielprojekt zeigen wie man eine Listbox relativ einfach erweitern kann. Ich tue dies am beispiel einer Liste mit Filmen. Über die Listbox soll der Titel, das Genre, eine Bewertung und ob man den Film bereits gesehen hat ersichtlich sein UND benutzerfreundlich veränderbar. In meinem Fall ist Schritt 1 zum erstellen einer solchen Listbox:

      Schritt 1: Wissen was man will
      Als erstes sollte man sich bewusst machen was die Listbox tun soll, da die listbox wie der namen schon sagt items auflistet macht man sich gedanken wie man ein Item gestalten möchte und welche funktionen sich dahinter verbergen sollen. Hier ein bild meines fertigen Controls mit erklärungen. Ein skizze ist übrigens immer ein kluger zug!


      Schritt 2: Welche Daten sollen angezeigt werden??
      Ohne Daten (also Filmtitel, Bewertung, etc) ist die eigene Listbox ja nutzlos. Man könnte diesen schritt eigentlich vor den 1. setzten aber heute zählt ja nur noch das design xD In meinem Beispiel habe ich eine Klasse "Movie" erstellt. Diese enthält alle relevanten Daten. mehr sollte es dazu nicht zu sagen geben.

      Schritt 3: Das Control vorbereiten
      In meinem Beispielprojekt geschieht dies überwiegend im Sub New der klasse MovieListbox. Da dort alles gut kommentiert ist belasse ich es dabei.
      Zur vorbereitung gehört auch eine maske für die anordnung der informationen im item. Die fertige Listbox ähnelt stark einer Tabelle wesshalb feste abstände unabdinglich sind.


      Schritt 4: Ein Item zeichnen
      So, kommen wir nun zu der wahrscheinlich wichtigsten funktion, dem zeichnen der items. Da man sich bereits gedanken gemacht hat wie die einzelnen informationen auf einem item angeordnet sind muss man lediglich im DrawItem-sub des Controls "beschreiben" wie das ganze hinterher aussehen soll. Ich habe in meinem Beispielprojekt denke ich die groben Möglichkeiten abgedeckt, nämlich: Text zeichenen, einfache Grafische Darstellung der Bewertung zeichnen und das laden einer Grafik aus einer Datei (für komplexere grafiken die sich mit GDI+ schwer realisieren lassen). Seht euch den Sub an und versucht alles nachzuvollziehen..

      Komplexere Grafiken lädt man am besten aus seperaten Dateien oder den Ressourcen


      Das erstellen der Bewertungsanzeige erfordert GDI+, mathematik und wirrwarrverständnis



      Schritt 5: Der User will mit den Daten arbeiten!
      Eigentlich wäre das Control soweit fertig, da eigentlich aber eigentlich ein sch***-wort ist verbessern wir das ganze: Der User soll mittels Mausklicks informationen der Items manipulieren können. In meinem Beispielprojekt geschieht dies über mehrere Wege: eigenen Dialog anzeigen lassen (das ist bei komplexeren Datenstrukturen sinnvoll), Verwendung eines Kontextmenüs, einfaches klicken um die Bewertung zu verändern und den "Schon gesehen?" Status zu verändern. Dieser Schritt macht eigentlich die gesamte Benutzerfreundlichkeit aus, je schneller und einfacher man die informationen anpassen kann desto besser ist es! Zu sagen wäre hier noch, dass die Verwendung von Properties und eigenen Events das Programmhandling stark verbessern könnnen.


      Das wäre auch schon alles. Mein Beispielprojekt findet ihr im Dateianhang. Wer das Control in seinem Projekt verwenden will kann dies gerne tun, eine kleine PN mit dankeschön und eine namentliche erwähnung sind mir genug xD
      Dateien
      Hier ein kleines Update:
      Jedem der das ganze getestet hat wird feststellen, dass das control (zumindest bei einer längeren liste) zum flackern neigt. das liegt daran, dass sich das control komplett neu zeichnet - auch wenn sich im schlechtesten fall nur der kleine ausschnitt des "schon gesehen?" auges verändert. Das kann natürlich ausgebessert werden indem man dem me.invalidate einen bereich zuweist der neu zu zeichnen ist. Hier mal zwei beispiele die selbsterkärend sein sollten:

      VB.NET-Quellcode

      1. ''Schon gesehen ändern
      2. ' Me.Invalidate() 'das Control wird neugezeichnet, da sich daten verändert haben
      3. Dim ly As Integer = CInt(Math.Ceiling((e.Y / ItemHeight))) - 1 'findet heraus welches item vom sichtbaren listenbegin ausgehen angeklickt wurde
      4. ly = ly * ItemHeight 'berechnet die obere kante des angeklickten item relativ zum sichtbaren listenbegin
      5. Me.Invalidate(New Rectangle(WidthTitel + WidthGenre + WidthBewertung, ly, WidthGesehen, ItemHeight)) 'nur ein kleiner bereich (der der sich geändert hat) wird neugezeichnet. so entsteht kein flackern


      VB.NET-Quellcode

      1. ''Bewertung ändern
      2. 'Me.Invalidate() 'das Control wird neugezeichnet, da sich daten verändert haben
      3. Dim ly As Integer = CInt(Math.Ceiling((e.Y / ItemHeight))) - 1 'findet heraus welches item vom sichtbaren listenbegin ausgehen angeklickt wurde
      4. ly = ly * ItemHeight 'berechnet die obere kante des angeklickten item relativ zum sichtbaren listenbegin
      5. Me.Invalidate(New Rectangle(WidthTitel + WidthGenre, ly, WidthBewertung, ItemHeight)) 'nur ein kleiner bereich (der der sich geändert hat) wird neugezeichnet. so entsteht kein flackern


      problematisch wird es bei verwendung des contextmenüs, dort kann kein e.y abgerufen werden. eine lösung wäre bei jedem klick auf das control die y-komponente in eine externe variable zu speichern sodass sie für diesen fall zur verfügung steht..

      wer verbesserungsvorschläge hat oder sich zu dem control äußern möchte darf natürlich posten! xD
      lg
      @ nxtman
      sry aber ich versteh deine frage nicht richtig...
      Soweit ich verstanden habe willst du die gesamte liste durchlaufen und dabei einzelne informationen der items auslesen (nur schon gesehen und den titel?).
      vllt hilft dir das weiter:

      VB.NET-Quellcode

      1. 'Auch wenn es in dieser listbox nicht mehr ersichtlich ist lassen sich die filme anwählen wie ein ganz normales listboxitem.
      2. 'durch modifizieren der zeichenroutine lässt sich das natürlich farblich hervorheben.
      3. If MovieListbox1.SelectedIndex <> -1 Then
      4. Dim tmp As Movie = DirectCast(MovieListbox1.SelectedItem, Movie) 'das gewählte item (typ objekt) muss in den enstprechenden typ umgewandeltwerden damit man zugriff auf die properties hat
      5. MsgBox(tmp.Titel)
      6. End If
      7. 'So kann die komplette liste mittels for-each-schleife durchlaufen werden
      8. For Each M As Movie In MovieListbox1.Items
      9. MsgBox(M.Titel)
      10. Next