VB.Net ListView Selektion rückgängig machen

  • VB.NET
  • .NET (FX) 4.0

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von keineahnung.

    VB.Net ListView Selektion rückgängig machen

    Hallo zusammen,

    ich befinde mich grade bei einem Problem in der .NET Desktopentwicklung (Visual Basic, .NET Framework 4.7.2):
    Und zwar habe ich (für ein Datensicherungsprogramm) eine ListView, zum Speichern von Quell -und Zielpfäden etc.:


    Hat man nun ein Item in der ListView selektiert und man drückt F2, dann kommt man in den (von mir erstellten) Bearbeitungsmodus:


    Wenn man nun ein anderes Item in dieser ListView auswählt, dann werden die TextBoxen auf ein gültiges Pfad-Format (Quell -und Zielpfad) überprüft.
    [Also, dass z. B. am Anfang des Pfads ein gültiger Laufwerksbuchstabe vorhanden ist]

    --> Wenn das Format ok ist, dann wird der Bearbeitungsmodus einfach geschlossen.
    --> Wenn das Format NICHT ok ist, soll diese Selektion rückgängig gemacht werden.

    Hierfür greife ich auf das SelectedIndexChanged-Event dieser ListView zurück:

    VB.NET-Quellcode

    1. Private Sub EntriesView_SelectedIndexChanged(sender As Object, e As EventArgs) Handles EntriesView.SelectedIndexChanged
    2. If currentEditingCntrl.Hide() = False Then
    3. For Each iItem As ListViewItem In EntriesView.SelectedItems
    4. iItem.Selected = False
    5. Next
    6. currentEditingCntrl.AttachedListViewItem.Selected = True
    7. End If
    8. End Sub

    currentEditingCntrl ist eine Instanz von einer von mir erstellten Klasse, die Methoden für das Anzeigen des Bearbeitungsmodus bereitstellt.
    Mit der Hide()-Funktion verschwindet der Bearbeitungsmodus von der Bildschirmoberfläche und die Funktion gibt "True" zurück,
    es sei denn, es liegt ein ungültiges Pfadformat vor, dann gibt die Funktion ein "False" zurück und zeigt dem User eine MessageBox, die die Ursache des Problems beschreibt.
    Mit dem inneren Code in der If-Klammer setze ich die ListView-Selektion auf ihren Ursprung zurück.

    Jetzt zum Problem:
    Durch das Setzen der Selected-Property der ListView wird genau das gleiche Ereignis [SelectedIndexChanged] erneut aufgerufen
    und das Programm gerät in eine MessageBox-Endslosschleife, da die Hide()-Fuktion wieder erneut aufgerufen wird.

    Wie könnte man es ermöglichen, dass die MessageBox nur einmal angezeigt wird und die ListView-Selektion gleichzeitig auf ihren Ursprung zurückkehrt?

    Danke für eure wertvolle Zeit und Danke im voraus!

    P. S. bin ganz neu in dem Forum
    LG keineahnung :)
    Willkommen im Forum.

    Du postest in WPF und verwandte Technologien, Deine Screenshots und Dein Code klingen aber eher nach WinForms. Bitte klären.
    ListView … in 99 % der Fälle ist ein DGV die bessere Wahl.

    Da mir jetzt nicht klar ist, ob die Eigenklassen einen Einfluss haben, köntest Du erstmal probieren:

    VB.NET-Quellcode

    1. For Each iItem As ListViewItem In EntriesView.SelectedItems
    2. If EntriesView.SelectedItems(0) Is iItem Then Continue For
    3. iItem.Selected = False
    4. Next


    btw: If currentEditingCntrl.Hide() = False Then: Boolean-Vergleiche mit True sind überflüssig.
    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.
    Hey, vielen Dank für die Antwort!

    Hab das Problem schon gelöst, hab mehrere Methoden entwickelt und geprüft, bis ich zu dem Entschluss gekommen bin,
    dass durch das ständige Aufrufen des selben Events (ItemSelectionChanged) meine Anwendung in einen Überlauf versetzt wird (aber ohne

    VB.NET-Quellcode

    1. ​System.StackOverflowException
    ).
    Mit einem

    VB.NET-Quellcode

    1. ​Threading.Thread.Sleep(...)
    könnte man das Ganze lösen.
    Erst bei ner Entgegenwirkung mit ca. 800ms (wenn ich es noch richtig in Erinnerung habe) kann gegen diesen Überlauf entgegengewirkt werden,
    aber das dauert zu lange. Dann hab ich was anderes ausprobiert. Mit dem beistehendem Code kann man bestimmt nichts anfangen.
    Aber ich hab meiner Klasse (EntriesViewEditingControl) einen Boolean angefügt, der betimmt, ob MsgBoxes angezeigt werden.
    Diesen Boolean schalte ich immer hin und her, weil die MsgBox genau 2x aufgerufen wird...

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports Datensicherung.Language
    3. Imports Datensicherung.ProfileTag
    4. Imports Datensicherung.ProfileTag.ProfileContent
    5. Imports Datensicherung.ProfileTag.ProfileContent.Entry
    6. Public Class EntriesViewEditingControl
    7. '[...unwichtiger Code...]
    8. Public Function TryHide() As Boolean
    9. If IsNothing(AttachedListViewItem) Then Return True
    10. If DeleteItemWhenAllPathsEmpty Then
    11. If PathCouldExist(cbSourcePath.Text).messages.Contains(mEmptyPath) And PathCouldExist(cbDestinationPath.Text).messages.Contains(mEmptyPath) Then
    12. ForceHide()
    13. AttachedListViewItem.Remove()
    14. AttachedListViewItem = Nothing
    15. Return True
    16. End If
    17. End If
    18. With PathCouldExist(cbSourcePath.Text)
    19. If .result = False Then
    20. SelectionChangingProcessActive = True
    21. For Each iItem As ListViewItem In CurrentListView.SelectedItems
    22. iItem.Selected = False
    23. Next
    24. For Each iItem As ListViewItem In CurrentProfilesView.SelectedItems
    25. iItem.Selected = False
    26. Next
    27. AttachedListViewItem.Selected = True
    28. CurrentProfilesItem.Selected = True
    29. SelectionChangingProcessActive = False
    30. If ShowMessageBoxes Then MessageBox.Show(tt.ToolTipTitle & newLine & .messages(0), "Warnung", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    31. cbSourcePath.Select()
    32. Return False
    33. End If
    34. End With
    35. With PathCouldExist(cbDestinationPath.Text)
    36. If .result = False Then
    37. SelectionChangingProcessActive = True
    38. For Each iItem As ListViewItem In CurrentListView.SelectedItems
    39. iItem.Selected = False
    40. Next
    41. For Each iItem As ListViewItem In CurrentProfilesView.SelectedItems
    42. iItem.Selected = False
    43. Next
    44. AttachedListViewItem.Selected = True
    45. CurrentProfilesItem.Selected = True
    46. SelectionChangingProcessActive = False
    47. If ShowMessageBoxes Then MessageBox.Show(tt.ToolTipTitle & newLine & .messages(0), "Warnung", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    48. cbDestinationPath.Select()
    49. Return False
    50. End If
    51. End With
    52. ForceHide()
    53. Return True
    54. End Function
    55. Public Sub ForceHide()
    56. For Each iControl As Control In {cbElementType, cbSourcePath, btnChangeSourcePath, cbDestinationPath, btnChangeDestinationPath, cbTransferMethod, cbMessageNonExistence}
    57. CurrentListView.Controls.Remove(iControl)
    58. Next
    59. CurrentListView.MultiSelect = True
    60. CurrentProfilesView.MultiSelect = True
    61. End Sub
    62. '[...unwichtiger Code...]
    63. End Class


    VB.NET-Quellcode

    1. ​Private Sub EntriesView_ItemSelectionChanged(sender As Object, e As ListViewItemSelectionChangedEventArgs) Handles EntriesView.ItemSelectionChanged
    2. If currentEditingCntrl.SelectionChangingProcessActive Then
    3. Exit Sub
    4. End If
    5. If IsNothing(currentEditingCntrl.AttachedListViewItem) = False Then
    6. If e.ItemIndex <> currentEditingCntrl.AttachedListViewItem.Index And e.IsSelected = True Then
    7. 'Das ist nötig, weil durch den ständigen Aufruf des gleichen Events die Anwendung in einen Überlauf gerät
    8. currentEditingCntrl.ShowMessageBoxes = Not currentEditingCntrl.ShowMessageBoxes
    9. currentEditingCntrl.TryHide()
    10. End If
    11. End If



    Trotzdem vielen Dank für die Antwort!

    LG keineahnung :thumbsup: