ListView Ausgewähltes Item

  • VB.NET
  • .NET (FX) 4.0

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von ~blaze~.

    ListView Ausgewähltes Item

    Ich habe eine ListView und möchte zur Laufzeit wissen, welches Item ausgewählt ist. Und je nach Item eine andere Aktion durchführen.

    Ich bin soweit das ich unter SelectedIndexChanged, Select Case stehen habe.

    Meine Frage nun ist:
    Was muss ich mit der Select Case Funktion abrufen?

    Hoffe auf schnelle antworten.
    Serpifeu7
    Ich habe es mit FocusedItem und SelectedItems bereits versucht! (Listview1.SelectedItems)
    Bei beiden kommt der Fehler:
    =-Operator ist für die Typen "System.Windows.Forms.ListviewItem" und "Integer" nicht definiert!
    Multiselect ist aus, und ich möchte es ändern sobald ein anderes Item gewählt ist. Das mit der vererbten Klasse versteh ich irgendwie nicht!

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

    Dann müsstest du vllt. eher auf SelectedIndices ausweichen?

    Du kannst eine Klasse von ListViewItem erben lassen, diese dann im Code hinzufügen. Gibst du der Klasse bspw. einen Delegaten bei der Instantiierung mit, so kannst du ihn in einer Property zwischenspeichern und über einen Cast später ausführen - oder du machst ähnliches mit einer Beschreibung, was ausgeführt werden soll.
    Falls dir das zu anspruchsvoll ist, versuch's mal über SelectedIndices.

    Gruß
    ~blaze~
    Falls dir ausreicht, zu wissen, ob das 1. 2. 3.... oder X.te Item markiert ist, sollte dies hier reichen (aufgerufen im SelectedIndexChanged-Event

    VB.NET-Quellcode

    1. Private Sub ListBox1_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
    2. Select Case ListBox1.SelectedIndex
    3. Case 0 ' erster Eintrag
    4. ' machewas
    5. Case 1 ' zweiter Eintrag
    6. ' mwach was anderes
    7. Case 2 ' dritter Eintrag
    8. ' mach wieder was anderes
    9. ' usw. usw. usw.
    10. End Select
    11. End Sub
    huch.... "view" überlesen.
    dann halt "ListView1.SelectedItems(0)" nehmen (gleiches Event), sobald du dich überzeugt hast, das überhaut etwas ausgewählt wurde.
    und damit kommst du ja dann auch Text usw. ran, um dann mit Select case weiter vergleichen zu können.
    Mach es mal wie folgt. Ich glaub wichtig ist das du erst prüfst ob überhaupt was selektiert ist, ich glaub das Event wird auch ausgelöst wenn die Selektion aufgehoben wird. SelectedIndices gibt dir einen Array vom typ Integer zurück, mit den Selektierten Indexes

    VB.NET-Quellcode

    1. Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView1.SelectedIndexChanged
    2. If ListView1.SelectedIndices.Count > 0 Then
    3. Select Case ListView1.SelectedIndices(0)
    4. Case 0
    5. Case 1
    6. 'etc....
    7. End Select
    8. End If
    9. End Sub

    ~blaze~ schrieb:

    Gibst du der Klasse bspw. einen Delegaten bei der Instantiierung mit, so kannst du ihn in einer Property zwischenspeichern und über einen Cast später ausführen - oder du machst ähnliches mit einer Beschreibung, was ausgeführt werden soll.


    Könntest du das für mich näher erläutern? Mit einem Beispiel? Was hat jetzt Cast damit zu tun?
    Also wenn ich das von @~blaze~ richtig verstanden habe müsste das so in der Art gehen.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. Dim l1 As New ListViewItemEx(AddressOf Opt1)
    4. l1.Text = " Item 1"
    5. ListView1.Items.Add(l1)
    6. Dim l2 As New ListViewItemEx(AddressOf Opt2)
    7. l2.Text = " Item 2"
    8. ListView1.Items.Add(l2)
    9. End Sub
    10. Private Sub Opt1()
    11. MessageBox.Show("Opt1")
    12. End Sub
    13. Private Sub Opt2()
    14. MessageBox.Show("Opt2")
    15. End Sub
    16. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    17. Dim items = ListView1.SelectedItems()
    18. For Each item As ListViewItemEx In items
    19. item.Action.Invoke()
    20. Next
    21. End Sub
    22. End Class
    23. Public Class ListViewItemEx
    24. Inherits ListViewItem
    25. Public Property Action As Action
    26. Public Sub New(action As Action)
    27. MyBase.New()
    28. Me.Action = action
    29. End Sub
    30. End Class



    Korrigiert mich jedoch wenn ich falsch liege^^

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Und wo kommt da Cast vor?

    Ich habe auch so verstanden, dass man statt action.Invoke so machen soll:

    VB.NET-Quellcode

    1. Public Class ListViewItemEx
    2. Inherits ListViewItem
    3. Private Property _Action As Action
    4. Public Sub New(action As Action)
    5. MyBase.New()
    6. Me._Action = action
    7. End Sub
    8. Public Sub DoAction()
    9. If _Action IsNot Nothing Then Me._Action()
    10. End Sub
    11. End Class
    12. 'in der Form dann
    13. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    14. Dim items = ListView1.SelectedItems()
    15. For Each item As ListViewItemEx In items
    16. item.DoAction()
    17. Next
    18. End Sub

    Denke wenn man es global mit ListViewItems hält muss man es ja casten

    VB.NET-Quellcode

    1. For Each item As ListViewItem In items
    2. Dim itemEx = TryCast(item, ListViewItemEx)
    3. If Not itemEx Is Nothing Then itemEx.Action.Invoke()
    4. Next


    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Es könnten aber theoretisch normale ListviewItems auch in der Listview vorhanden sein (warum auch immer).
    Diese haben natürlich keine Property "Action".

    Deswegen wird hier versucht es in ListViewItemEx zu casten. Wenn dies nicht funktioniert hat (Weil es ein normales ListViewItem ist) ist es ja Nothing und somit wird auch das Invoke nicht ausgeführt.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Mehr oder weniger. ;) Es war gemeint, dass zum Aufrufen des Delegaten ja erst ein Cast zu ListViewItemEx erfolgen muss, da sonst keine Zugriffsmöglichkeit besteht. Da der Cast fehlschlagen würde, wäre ein Nicht-ListViewItemEx drin, muss das vorher nat. einbezogen werden (z.B. TryCast und Is Nothing-Überprüfung).

    Die Aktion soll dann bei einer Aktivierung eines Items eben ausgeführt werden oder, wenn ein Button betätigt wird, etc.

    Gruß
    ~blaze~
    TypeOf ... Is ... würde eine doppelte Überprüfung vornehmen, wenn man im Anschluss gleich einen Cast durchführt (sofern der Compiler es nicht wegoptimiert), daher ist es praktischer, einfach TryCast zu verwenden, da eine Überprüfung auf Null effizienter sein sollte.

    Noch feiner wäre es übrigens, eine BindingList(Of T) zu verwenden und anschließend die ListViewItems über eine weitere Klasse zu erzeugen (d.h. eben eine Klasse von ListView erben lassen und dort auf Änderungen von System.ComponentModel.IBindingList, oder wie die heißt, hören oder eben eine Verwaltung für die typische DataSource schreiben. Außerdem eben noch eine DataTemplate-Klasse einführen, die anschließend die ListViewItems und zugehörige Icons aus den Daten erzeugt). Damit hätte man auch die manuelle Verwaltung nicht mehr nötig und könnte einfach über eine BindingList(Of T) arbeiten. TreeView würde ziemlich analog funktionieren.

    Ach ja: Mit Delegaten kann man wirklich wunderbare Sachen machen. Ich wollte schon mal irgendwann ein kleines Beispiel veröffentlichen, hatte aber bisher noch keine Zeit...

    Gruß
    ~blaze~

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