ToolStripDropDown Hinzufügen von MenuItem aus Pfad

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    ToolStripDropDown Hinzufügen von MenuItem aus Pfad

    Guten Morgen,

    erstmal nachträglich frohe Weihnachten :) und dann meine Frage:

    In einem ToolStripDropDown werden Items hinzugefügt. Nun wollte ich, dass auch aus dem Pfad die Unterordner, als Ordner (bzw. MenuItem) in den DropDown hinzugefügt werden. Hoffe, dass annähernd verständlich.
    Wie muss ich da vorgehen? Muss erst geprüft werden, ob es Unterverzeichnisse gibt und dann werden diese erstellt? Und anschließend die Items verteilt?

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class FileObject
    2. Inherits ToolStripMenuItem
    3. Public Property Path As String
    4. End Class
    5. Dim str As String = "\\rs-win1\ablage\ISO\Formulare\1_Allgemein\3_Hinweislisten"
    6. Private Sub fo_click(ByVal sender As Object, ByVal e As EventArgs)
    7. Dim tmp As FileObject = CType(sender, FileObject)
    8. Process.Start(tmp.Path & "\" & tmp.Name)
    9. End Sub
    10. Private Sub TSDD_Hinweislisten_DropDownOpening(sender As Object, e As EventArgs) Handles TSDD_Hinweislisten.DropDownOpening
    11. Dim di As DirectoryInfo = New DirectoryInfo(str)
    12. Dim fi As FileInfo()
    13. fi = di.GetFiles("*.pdf", SearchOption.AllDirectories)
    14. Dim fo As FileObject = Nothing
    15. TSDD_Hinweislisten.DropDownItems.Clear()
    16. For i As Integer = 0 To fi.Length - 1
    17. fo = New FileObject()
    18. fo.Name = fi(i).Name
    19. fo.Text = Path.GetFileNameWithoutExtension(fi(i).Name)
    20. fo.Path = fi(i).DirectoryName
    21. With TSDD_Hinweislisten
    22. .DropDownItems.Add(fo)
    23. .DropDownDirection = ToolStripDropDownDirection.AboveRight
    24. End With
    25. AddHandler fo.Click, AddressOf fo_click
    26. Next i
    27. Dim liste As Object = TSDD_Hinweislisten.DropDownItems.Cast(Of ToolStripMenuItem).OrderBy(Function(n) n.Text).ToArray
    28. TSDD_Hinweislisten.DropDownItems.AddRange(liste)
    29. End Sub



    Freue mich auf eine Rückmeldung.

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

    Sam85 schrieb:

    Hoffe, dass annähernd verständlich.
    naja, man ahnt, was du willst, aber wenn du eine Beschreibung unterr Verwendung korrekter Begriffe verfassen könntest, dann könntest du das auch programmieren.
    Also dieses hier:
    Nun wollte ich, dass auch aus dem Pfad die Unterordner, als Ordner (bzw. MenuItem) in den DropDown hinzugefügt werden.
    Was ist: "dem Pfad"?
    "als Ordner (bzw. MenuItem)" Wassnu: Ordner oder MenuItem?

    Muss erst geprüft werden, ob es Unterverzeichnisse gibt und dann werden diese erstellt?
    Hä? Wenn es Unterverzeichnisse gibt, kannst du sie doch nicht mehr erstellen - dann sind sie ja schon da.
    Was meinst du mit "erst"?

    Versuch mal eine Beschreibung, die beschreibt, was genau wann genau passieren soll.
    @ErfinderDesRades
    Gut dann versuche ich es mal besser... :)

    Es werden PDF Dokumente aus einem Verzeichnisstamm Dim str As String = "\\rs-win1\ablage\ISO\Formulare\1_Allgemein\3_Hinweislisten" in das ToolStripDropDown eingefügt. Dabei werden alle PDF Dokumente, unabhängig ob Haupt- oder Unterverzeichnis, zusammen eingefügt.

    Nun möchte ich, dass die PDF Dokumente aus den Unterverzeichnissen, nicht mit denen aus dem Hauptverzeichnis zusammengetragen werden.

    Wie muss ich dabei vorgehen? Aktuell durchlaufe ich den gesamten Verzeichnisstamm fi = di.GetFiles("*.pdf", SearchOption.AllDirectories) und gebe anschließend alles, was dem Kriterium entspricht, wieder aus. Muss ich demnach ein weiteres FileObject in die Schleife implementieren, um den laufenden Verzeichnisstamm des, durch die Schleife erfassten Dokumentes, als MenuItem in das ToolStripDropDown hinzuzufügen und dort, das aktuelle Dokument in der Schleife hinzuzufügen?

    VB.NET-Quellcode

    1. For i As Integer = 0 To fi.Length - 1
    2. fo = New FileObject()
    3. fo.Name = fi(i).Name
    4. fo.Text = Path.GetFileNameWithoutExtension(fi(i).Name)
    5. fo.Path = fi(i).DirectoryName
    6. With TSDD_Hinweislisten
    7. .DropDownItems.Add(fo)
    8. .DropDownDirection = ToolStripDropDownDirection.AboveRight
    9. End With
    10. AddHandler fo.Click, AddressOf fo_click
    11. Next i

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Sam85“ ()

    SearchOption.AllDirectories ist nicht wirklich gut, weil das liefert ja keinen verzeichnisbaum, sondern nur eine Liste von Dateien.
    Um den Verzeichnisbaum zu durchlaufen musst du eine rekursive Funktion proggen, die von jedem Verzeichnis die Unterverzeichnisse ausliest.
    In der Methode kann man Code unterbringen, der paralell dazu einen entsprechenden MenüBaum aufbaut.
    Damit wäre der Verzeichnisbaum in einem MenüBaum abgebildet.

    Das kann am Ende aber ziemlich unbenutzbar werden - stell dir vor, du stösst auf ein Verzeichnis mit 100 Unterverzeichnissen.
    Ein Menü mit 100 UnterMenüs ist unbrauchbar, weil bildschirm zu klein.

    Dasselbe Problem, wenn ein Verzeichnis 100 pdfs enthält.

    Oder auch nur 30.



    Nochmal zu Rekursion: Ist dir der Begriff bekannt?
    Das ist ein pfiffiger Algorithmus, der in Abwandlungen vergleichsweise häufig auftritt.
    Leider muss mans immer wieder neu implementieren (anders als etwa den Sortier-Algo) und den Erfordernissen anpassen.
    @ErfinderDesRades

    Sind diese Quellen zur Rekursion geeignet? Link 1, Link 2, Link 3, Link 4

    Ja ich verstehe dein Bedenken bzgl. der n-ten Anzahl von Verzeichnissen, die Visuell nicht mehr sichtbar sind. Im Grunde obliegt mir die Anzahl der Verzeichnisse, somit wäre es zumindest für meine Zwecke in Ordnung.
    Was wäre deine Empfehlung bzw. eine Sinnvolle Lösung? Vermutlich ist es besser direkt ein Filter zu erstellen, um lediglich das wesentlich sichtbar zu machen ggf. mit DataSet?

    Wollte ich mein Vorhaben nun aber so abschließen wie geplant, unabhängig von der Sinnhaftigkeit...wie wäre dann die Sinnvolle Gestaltung einer Rekursiven Funktion?
    1. Durchlaufen der Verzeichnisse
      1. Wurde ein Unterverzeichnis gefunden, MenuItem erstellen
    2. Hinzufügen der Items in das jeweilige MenuItem

    Sam85 schrieb:

    Sind diese Quellen zur Rekursion geeignet?
    eher nicht.
    Dort wird das Grundprinzip gezeigt, anhand eines mathematischen Problems.
    Dein Problem ist aber die rekursive Traversion durch einen Datenbestand (also das Abklappern aller Nodes in einem Baum).
    vlt. googeln: "rekursive Traversion".
    oder "directory rekursiv durchsuchen" oder sowas.
    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!
    @ErfindesDesRades
    dann ist dieser Link :) besser für die Rekursive Traversion?

    @RodFromGermany
    nicht unbedingt, es geht mir eher um die Darstellung der einzelnen Dokumente, gegliedert nach den entsprechenden Unterverzeichnis.
    Wie auf dem Picture sieht es aktuell aus aber die Verzeichnis Struktur sieht aus wie auf Picture2 und diese Struktur wollte ich umsetzen.
    Bilder
    • Picture.PNG

      101,33 kB, 339×454, 81 mal angesehen
    • Picture2.PNG

      13,35 kB, 318×342, 76 mal angesehen
    @Sam85 So was wie Salamander oder Total Commander?
    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!

    Sam85 schrieb:

    dann ist dieser Link besser für die Rekursive Traversion?
    Jo, insbesondere weil der Abschnitt "Struktur-Aufbau" ist genau dein Vorhaben: Du willst anhand des baumartigen Verzeichnis-Struktur einen MenüItem-Struktur aufbauen.
    Ich hätte dir das Tut auch selbst empfohlen, aber ich nahm an, du schreckest vor c# zurück.
    @ErfinderDesRades
    :) an und für sich bin ich dem Gegenüber aufgeschlossen, nur mangelt es mir noch am Verständnis und den Basics...bin leider kein Programmierer, noch Vollzeit damit beschäftigt. Aber interessant finde ich es, daher anschauen werde ich es mir und sollten noch fragen sein, melde ich mich.

    @RodFromGermany
    Hmm nein nicht so umfangreich :) ich denke für jemanden der sich auskennt, ist mein Vorhaben eher eine einfache Sache. Einfach ein DropDown Button (wie aktuell auch) nur mit Unterverzeichnis Struktur.

    Sam85 schrieb:

    ich denke für jemanden der sich auskennt, ist mein Vorhaben eher eine einfache Sache.
    Naja, so ein oder zwei Stündchen sitzt man trotzdem davor. Wie gesagt: Bei Rekursion ist jeder Algo eine Neu-Entwicklung - auch wenn das Grundprinzip immer dasselbe ist.
    Und mit den MenuItems muss man auch einiges herumprobieren - v.a. die Resourcenbereinigung - dynamische MenuItems macht man ja nicht alle Tage.

    Ich hab mal was gebastelt, bin neugierig, ob du ühaupt was mit anfangen kannst - weil ich hab ganz unbedarft auch anonyme Methoden verwendet, weil das bei Rekursion besonders günstig ist.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Mainmenu_Click(sender As Object, e As EventArgs) Handles btBuildFileMenu.Click, btRemoveFileMenu.Click, btFilesystem.Click
    2. Select Case True
    3. Case sender Is btBuildFileMenu : BuildFileMenu()
    4. Case sender Is btRemoveFileMenu : RemoveFileMenu()
    5. Case sender Is btFilesystem
    6. End Select
    7. End Sub
    8. Private Sub FileMenu_Click(sender As Object, e As EventArgs)
    9. Dim itm = DirectCast(sender, ToolStripMenuItem)
    10. Dim di = TryCast(itm.Tag, DirectoryInfo)
    11. If di.NotNull Then
    12. Msg("Directory '", di.Name, "' geklickst")
    13. Return
    14. End If
    15. Dim fi = DirectCast(itm.Tag, FileInfo)
    16. Msg(fi.FullName, Lf, " geklickst")
    17. End Sub
    18. Private Sub BuildFileMenu()
    19. Dim insertMenuItem As Func(Of ToolStripItemCollection, FileSystemInfo, Integer, ToolStripMenuItem) = _
    20. Function(itms, fsi, index)
    21. Dim itm = New ToolStripMenuItem(fsi.Name) With {.Tag = fsi}
    22. AddHandler itm.Click, AddressOf FileMenu_Click
    23. itms.Insert(index, itm)
    24. Return itm
    25. End Function
    26. Dim recurse As Action(Of ToolStripItemCollection, DirectoryInfo()) = _
    27. Sub(itms, dis)
    28. For Each di In dis
    29. For Each fi In di.GetFiles
    30. insertMenuItem(itms, fi, itms.Count)
    31. Next
    32. Dim itm = insertMenuItem(itms, di, 0)
    33. recurse(itm.DropDownItems, di.GetDirectories)
    34. Next
    35. End Sub
    36. recurse(btFilesystem.DropDownItems, {New DirectoryInfo("..\..\..")})
    37. End Sub
    38. Private Sub RemoveFileMenu()
    39. While btFilesystem.DropDownItems.Count > 0
    40. btFilesystem.DropDownItems(btFilesystem.DropDownItems.Count - 1).Dispose()
    41. End While
    42. End Sub

    Dateien
    • FileMenu00.zip

      (203,22 kB, 74 mal heruntergeladen, zuletzt: )