Contextmenü

  • VB.NET
  • .NET 5–6

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Contextmenü

    Hallo liebe Community,

    habe folgendes Problem dass ich nicht lösen kann

    Von meinem IMAP-Postfach werden sämtliche Ordner und Unterordner abgerufen und in ein ToolStripMenuItem gefüllt.

    Bei Rechtsklick werden mir zunächst die Ordner und deren Unterordner angezeigt.
    Nur wenn ein Unterordner auch einen Unterordner hat, wird dieser als Unterordner vom Hauptordner angezeigt.

    Zur Verdeutlichung:

    Gewünscht ist folgende Auflistung

    Hauptordner 1
    Unterordner 1.1
    Unter-Unterordner 1.1.1

    Stattdessen wird aber angezeigt

    Hauptordner 1
    Unterordner 1.1
    Unterordner 1.1.1 (Falsch)

    VB.NET-Quellcode

    1. Private Sub Add_contextmenu()
    2. dgvEmails.ContextMenuStrip = context_menu
    3. dgvEmails.ContextMenuStrip = context_menu
    4. tag_parent = 0
    5. tag_sub = 0
    6. For i = 0 To all_folders_array.Count - 1
    7. folder = all_folders_array(i)
    8. If Not all_folders_array(i).Contains("/") Then
    9. tag_parent += 1
    10. mainfolder = New ToolStripMenuItem(folder)
    11. mainfolder.Tag = tag_parent
    12. remove_to_folder.DropDownItems.Add(mainfolder)
    13. Else
    14. Dim folders2 = Contextmenu_add_subfolders(folder)
    15. End If
    16. Next
    17. End Sub
    18. Function Contextmenu_add_subfolders(folder As String) As String
    19. Dim Fullpath As String = folder
    20. Dim count_folder As Integer = Fullpath.Count(Function(c) c = "/"c) + 1
    21. Dim parts() As String = Fullpath.Split("/"c)
    22. Dim search_tag As String = ""
    23. Dim Child_folder As String = parts(count_folder - 1)
    24. If count_folder = 2 Then
    25. search_tag = tag_parent.ToString
    26. Else
    27. search_tag = "S" & tag_sub.ToString
    28. End If
    29. DurchlaufeContextMenuItems(context_menu, search_tag, Child_folder)
    30. End Function
    31. Private Sub DurchlaufeContextMenuItems(dropDownMenu As ToolStripDropDownMenu, search_tag As String, Child_folder As String)
    32. For Each item As ToolStripItem In dropDownMenu.Items
    33. If item.Tag IsNot Nothing AndAlso item.Tag.ToString() = search_tag Then
    34. Dim child As New ToolStripMenuItem(Child_folder)
    35. tag_sub += 1
    36. child.Tag = "S" & tag_sub
    37. mainfolder.DropDownItems.Add(child)
    38. AddHandler child.Click, AddressOf MenuItem_MouseClick
    39. Exit For
    40. End If
    41. If TypeOf item Is ToolStripDropDownItem Then
    42. Dim dropDownItem As ToolStripDropDownItem = CType(item, ToolStripDropDownItem)
    43. DurchlaufeContextMenuItems(dropDownItem.DropDown, search_tag, Child_folder)
    44. End If
    45. Next
    46. End Sub

    Vermute in der Sub "DurchlaufeContextMenuItems" enthält der rekursive Aufruf einen Fehler.

    Das selbe habe ich mit Treeview gemacht und dort werden die Nodes richtig dargestellt.
    Deshalb vermute ich beim rekursiv-Aufruf den Fehler.

    Bin für jede Hilfe dankbar.

    CodeTags gesetzt ~VaporiZed

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

    Willkommen im Forum.

    Bevor Du weitermachst, bitte die empfohlenen VS-Einstellungen verwenden. Contextmenu_add_subfolders ist z.B. als Function deklariert, gibt aber im Methodenkörper überhaupt keinen Wert an den Aufrufer zurück.

    VB.NET-Quellcode

    1. Dim dropDownItem As ToolStripDropDownItem = CType(item, ToolStripDropDownItem)
    2. DurchlaufeContextMenuItems(dropDownItem.DropDown, search_tag, Child_folder)
    dropDownItem.DropDown ist vom Typ ToolStripDropDown, DurchlaufeContextMenuItems will aber ein ToolStripDropDownMenu. Das ist offiziell erstmal inkompatibel.

    Wie und wo sind tag_parent, tag_sub, mainfolder, all_folders_array, folder und remove_to_folder deklariert?

    Sobald das beseitigt und geklärt ist, ist eine Fehlerfindung (besser) möglich.
    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.
    Alle vier sind wie folgt deklariert.

    Private tag_parent, tag_sub As Integer
    Private mainfolder As New ToolStripMenuItem
    Private all_folders_array As New ArrayList
    Private folder As String

    Die Function Contextmenu_add_subfolders habe ich zu private sub geändert, die 16. Zeile lautet nun >> Contextmenu_add_subfolders(folder)
    jo, wennde damit fertig bist, müssteste dich mit Rekursion beschäftigen.
    dazu habich im Tutorial-Bereich ein umfangreiches Tut verzapft, mit viele Beispiele. Unter anderem baue ich einen Menü-Baum aus einem Treeview auf - statt des Treeviews müssteste halt deine Imap-Ordnerstruktur hernemen

    Tree-Übungen - Rekursion Abschnitt "Rekursiver Aufbau"

    Aber wie gesagt: erstmal die empfohlenen einstellungen...
    Nachdem ich Option Strict auf On gesetzt und die Korrekturen gemacht habe sieht der Code nun wie folgt aus. Der einzige Fehler den ich nicht beseitigen konnte ist die Zeile
    DurchlaufeContextMenuItems(dropDownItem.DropDown, search_tag, Child_folder)

    VB.NET-Quellcode

    1. Private Sub Add_contextmenu()
    2. dgvEmails.ContextMenuStrip = context_menu
    3. tag_parent = 0
    4. tag_sub = 0
    5. For i = 0 To all_folders_array.Count - 1
    6. folder = all_folders_array(i).ToString
    7. If Not String.IsNullOrEmpty(folder) AndAlso Not folder.Contains("/") Then
    8. tag_parent += 1
    9. mainfolder = New ToolStripMenuItem(folder)
    10. mainfolder.Tag = tag_parent
    11. remove_to_folder.DropDownItems.Add(mainfolder)
    12. Else
    13. 'Dim folders2 = Contextmenu_add_subfolders(folder)
    14. Contextmenu_add_subfolders(folder)
    15. End If
    16. Next
    17. End Sub
    18. Private Sub Contextmenu_add_subfolders(folder As String)
    19. Dim Fullpath As String = folder
    20. Dim count_folder As Integer = Fullpath.Count(Function(c) c = "/"c) + 1
    21. Dim parts() As String = Fullpath.Split("/"c)
    22. Dim search_tag As String = ""
    23. Dim Child_folder As String = parts(count_folder - 1)
    24. If count_folder = 2 Then
    25. search_tag = tag_parent.ToString
    26. Else
    27. search_tag = "S" & tag_sub.ToString
    28. End If
    29. 'DurchlaufeContextMenuItems(context_menu, search_tag, Child_folder)
    30. End Sub
    31. Private Sub DurchlaufeContextMenuItems(dropDownMenu As ToolStripDropDownMenu, search_tag As String, Child_folder As String)
    32. For Each item As ToolStripItem In dropDownMenu.Items
    33. If item.Tag IsNot Nothing AndAlso item.Tag.ToString() = search_tag Then
    34. Dim child As New ToolStripMenuItem(Child_folder)
    35. tag_sub += 1
    36. child.Tag = "S" & tag_sub
    37. mainfolder.DropDownItems.Add(child)
    38. AddHandler child.Click, AddressOf MenuItem_MouseClick
    39. Exit For
    40. End If
    41. If TypeOf item Is ToolStripDropDownItem Then
    42. Dim dropDownItem As ToolStripDropDownItem = CType(item, ToolStripDropDownItem)
    43. DurchlaufeContextMenuItems(dropDownItem.DropDown, search_tag, Child_folder)
    44. End If
    45. Next
    46. End Sub


    CodeTags gesetzt ~VaporiZed

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

    ArrayList? Was steckt tatsächlich drin? Strings? Dann wäre ne List(Of String) besser, da typisiert.
    Und was ist nu remove_to_folder?
    Beim jetzigen Code wird DurchlaufeContextMenuItems überhaupt nicht mehr von außen aufgerufen.
    Du könntest probieren, ob das hier klappt:

    VB.NET-Quellcode

    1. DurchlaufeContextMenuItems(DirectCast(dropDownItem.DropDown, ToolStripDropDownMenu), search_tag, Child_folder)
    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.
    Add_contextmenu() hatte ich verkürzt veröffentlicht, unten die Langversion.

    remove_to_folder ist ein dropdownitem in der die Unterverzeichnisse reinkommen.
    Zeile 35 wurde nur temporär auskommentiert.

    Deinen Vorschlag mit DirectCast habe ich eingefügt, aber immernoch das selbe Ergebnis.

    In der Arraylist sind alle Verzeichnisse im Stringformat eingetragen, z.B.
    INBOX
    INBOX/Ordner
    INBOX/Ordner2/Ordner3
    usw.

    Ziel ist es, INBOX/Ordner1/Ordner2/Ordner3 im Contextmenü anzuzeigen.
    Es wird aber so dargestellt als ob Ordner3 ein Unterordner von INBOX ist.

    Mit den Treeview-Nodes klappt es einwandfrei, nur im Contextmenü will es nicht klappen.

    VB.NET-Quellcode

    1. Private Sub Add_contextmenu()
    2. Dim deleteOption As New ToolStripMenuItem("Löschen")
    3. AddHandler deleteOption.Click, AddressOf Delete_message
    4. context_menu.Items.Add(deleteOption)
    5. Dim remove As New ToolStripMenuItem("Verschieben")
    6. context_menu.Items.Add(remove)
    7. Dim remove_to_folder As New ToolStripMenuItem("in Ordner")
    8. remove.DropDownItems.Add(remove_to_folder)
    9. dgvEmails.ContextMenuStrip = context_menu
    10. tag_parent = 0
    11. tag_sub = 0
    12. For i = 0 To all_folders_array.Count - 1
    13. folder = all_folders_array(i).ToString
    14. If Not String.IsNullOrEmpty(folder) AndAlso Not folder.Contains("/") Then
    15. tag_parent += 1
    16. mainfolder = New ToolStripMenuItem(folder)
    17. mainfolder.Tag = tag_parent
    18. remove_to_folder.DropDownItems.Add(mainfolder)
    19. Else
    20. Contextmenu_add_subfolders(folder)
    21. End If
    22. Next
    23. End Sub


    Code-Tags eingefügt. ~Thunderbolt

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

    VaporiZed schrieb:

    Bevor Du weitermachst, bitte die empfohlenen VS-Einstellungen verwenden.
    zu den empfohlenen Einstellungen täte ich hinzufügen, den GeneralImport auf System.Collections ebenfalls rauszuwerfen.
    Da ist auch nur müll drin, wie etwa die olle ArrayList.
    Verwende stattdessen List(Of T).

    Ansonsten ist der neue Code nicht lesbar (bzw ich bin zu faul, mir das anzutun) - bitte mit den Forum-Mitteln formatieren.
    @Cem76 Willkommen im Forum.
    bitte mit den Forum-Mitteln formatieren.
    Das ist ein sehr wichtiger Hinweis, einige dienstältere Forum-Mitglieder scxhauen sich den Code gar nicht erst an, wenn er nicht formatiert ist.
    Tue dies (und editiere Deine obigen Posts entsprechend):
    Markiere den Code und drücke den VB.NET-Button über dem Post-Edit-Feld:

    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!

    FormFollowsFunction schrieb:

    als "Erledigt" makiert
    Der Kollege hat 4 Posts, das muss er noch lernen. ;)
    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!