Menüeinträge zur Laufzeit erstellen und markieren

  • VB.NET
  • .NET (FX) 3.0–3.5

Es gibt 57 Antworten in diesem Thema. Der letzte Beitrag () ist von tron25.

    Menüeinträge zur Laufzeit erstellen und markieren

    Hallo,

    ich lasse zur Laufzeit Menüpunkte wie folgt erstellen:

    VB.NET-Quellcode

    1. Dateiinhalt = New StreamReader(Userverzeichnis & "\" & My.Resources.DokuBilder & "\" & My.Resources.DokuBilder & ".pdb")
    2. Do Until Dateiinhalt.EndOfStream
    3. AktuelleZeile = Dateiinhalt.ReadLine()
    4. Dim DokubildEintrag As String() = AktuelleZeile.Split(",")
    5. Dim Dokubild As New ToolStripMenuItem With {.Name = "Menueeintrag", .Text = DokubildEintrag(0)}
    6. DokuBilderMenue.DropDown.Items.Add(Dokubild)
    7. AddHandler Dokubild.Click, AddressOf DokuBildLaden
    8. Loop
    9. Dateiinhalt.Close()


    Danach habe ich unterhalb des Menüpunktes "Dokubilder" mehrere neue Einträge mit den Namen, die im ersten Eintrag von "DokubilderEintrag" stehen. Nun möchte ich, wenn eines dieser Menüeinträge ausgewählt wurde, dass dieser Menüeintrag einen Haken bekommt. Ähnlich wie:

    VB.NET-Quellcode

    1. DokubilderMenue.checked = true


    Mit dem folgenden Code bekomme ich den Index des ausgewählten Menüeintrages:

    VB.NET-Quellcode

    1. Public Sub DokuBildLaden(Sender As Object, e As EventArgs)
    2. Dim X As Integer
    3. X = DokuBilderMenue.DropDownItems.IndexOf(Sender)
    4. ...
    5. End sub


    Weiß jemand, wie das bei solchen Menüpunkten funktioniert?

    CodeTags korrigiert ~VaporiZed

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

    Bevor Du weitermachst, bitte die empfohlenen VS-Einstellungen verwenden. AktuelleZeile.Split(",") ist nämlich Option Strict Off, genauso m.E. X = DokuBilderMenue.DropDownItems.IndexOf(Sender)

    Hättest Du das im Designer mal nachgebaut, hättest Du rausgefunden, dass ein ToolStripMenuItem auch die Eigenschaft CheckOnClick hat. Damit kommst Du weiter und kannst Dir ggf. den ClickEventHandler ersparen.
    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.
    Die CheckOnClick-Eigenschaft habe ich beim Erstellen hinzugefügt. Jetzt wird, wie erwartet Das Häkchen gesetzt bzw. entfernt. Nun möchte ich, je nach dem Zustand unterschiedlichen Code ausführen lassen. Allerdings kann ich die "Checked"- bzw. "CheckedState"-Eigenschaft nicht abfragen bzw. setzen. Außerdem möchte ich, dass, wenn ein Menüpunkt aktiviert wird, alle anderen Menüpunkte entmarkiert werden. Dazu müßte ich auch manuell den Hacken setzen können:

    VB.NET-Quellcode

    1. X = DokuBilderMenue.DropDownItems.IndexOf(Sender)
    2. If DokuBilderMenue.DropDownItems.Item(X).checked = False Then
    3. DokubildAktiviert = False
    4. Else
    5. DokubildAktiviert = True
    6. End If

    Auf dieser Menüebene gibt es 7 Menüpunkte, die permanent vorhanden sind. Der erste zur Laufzeit erstellte Eintrag fängt demnach mit dem Index 7 an. In X steht der Index des aufrufenden Menüpunktes.

    Kannst du mir bitte da auch helfen, wie die Haken bei den anderen manuell gelöscht werden können?
    Du nimmst z.B. in einer For-Schleife jedes Item aus DokuBilderMenue.DropDownItems her und setzt dessen Checked auf False - außer beim angeklickten. Woran scheitert es?
    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.
    @tron25 machst Du

    VB.NET-Quellcode

    1. DokubildAktiviert = okuBilderMenue.DropDownItems.Item(X).Checked
    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!
    Das Problem war, das der Assistent beim Schreiben das Wort "checked" nicht als Schlüsselwort angeboten hat. Die Schleife, die alle Menüpunkte aktivieren soll, funktioniert. Die Abfrage danach funktioniert leider nicht:

    VB.NET-Quellcode

    1. X = DokuBilderMenue.DropDownItems.IndexOf(Sender)
    2. For Each Eintrag In DokuBilderMenue.DropDownItems
    3. 'Ein Seperator hat keinen Text und kann auch nicht aktiviert werden.
    4. If Eintrag.text <> "" Then
    5. 'Der aufrufende Eintrag soll ausgelassen werden.
    6. If Eintrag.text <> Sender.ToString Then
    7. Eintrag.checked = False
    8. End If
    9. End If
    10. Next
    11. If DokuBilderMenue.DropDownItems.Item(X).checked = False Then
    12. DokubildAktiviert = False
    13. Else
    14. DokubildAktiviert = True
    15. End If


    Es erschein folgende Fehlermeldung an der Position der Abfrage:

    VB.NET-Quellcode

    1. Fehler BC30456 "checked" ist kein Member von "ToolStripItem".


    Außerdem wäre es etwas eleganter, wenn nur die neu erzeugten Menüeinträge geprüft werden und nicht alle. Dann bräuchte ich auch nicht nach dem Seperator prüfen.

    tron25 schrieb:

    folgende Fehlermeldung
    Dann ist Dein Code in Post #3 offensichtlich falsch.
    In meinem von Dir ignorierten Post hatte ich "checked" groß geschrieben.
    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!
    Das habe ich gesehen. Es spielt keine Rolle, ob ich selbst das Wort groß oder klein schreibe. Es erscheint jedesmal die gleiche Meldung. Auch wenn ich dein Beispiel oder meine Abfrage nutze, funktioniert es nicht.

    Wenn ich statt dem laufzeitig erstellten Menüpunkt einen permanenten einsetze, funktioniert es. Da kann ich auch alles klein schreiben und der Editor wandelt die Schlüsselwörter in die richtige Schreibweise.

    tron25 schrieb:

    Wenn ich statt dem laufzeitig erstellten Menüpunkt einen permanenten einsetze, funktioniert es.
    Dann sieh Dir mal den Designer-Code dazu an.
    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!
    Sorry, aber wo finde ich den Designercode?

    Ich habe jetzt ein neues Projekt erstellt und angehängt. Da bekomme ich auch die gleiche Fehlermeldung. Außerdem ist mir beim Testen aufgefallen, dass, wenn ein Menüpunkt aktiviert wird, gleichzeitig alle anderen Menüpunkte in der gleichen Hirarchieebene deaktiviert werden. Nun bräuchte ich nur die Möglichkeit, herauszufinden, ob der aufrufende Menüpunkt aktiviert ist.
    Dateien
    DokuBilderMenue.DropDownItems ist eine Auflistung von ToolStripItems
    Ein ToolStripItem hat keine Checked-Property - egal wie gross geschrieben.

    ToolStripMenuItem - das ist ein ToolStripItem, was eine Checked-Property hat.
    Vermutlich musste DokuBilderMenue.DropDownItems.Item(X) nur auf ToolStripMenuItem casten, und dann gehts erstmal.
    @ErfinderDesRades Aber ein ToolStripMenuItem.
    @tron25 Probier mal dies:

    VB.NET-Quellcode

    1. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. For X As Integer = 0 To 4
    3. Dim Dokubild As New ToolStripMenuItem With {.Name = "Menueeintrag", .Text = "Untermenue " & X, .CheckOnClick = True}
    4. TestMenue.DropDown.Items.Add(Dokubild)
    5. 'AddHandler Dokubild.Click, AddressOf DokuBildLaden
    6. AddHandler Dokubild.CheckedChanged, AddressOf TestMenue_CheckedChanged
    7. Next X
    8. End Sub
    9. Private Sub TestMenue_CheckedChanged(sender As Object, e As EventArgs) Handles TestMenue.CheckedChanged
    10. Dim mnu = CType(sender, ToolStripMenuItem)
    11. Label1.Text = mnu.Checked.ToString()
    12. End Sub

    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!
    Das große Problem ist immer noch, dass mit Option Strict Off programmiert wird. Post#6 geht gar nicht unter On
    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.
    So, nun habe ich es, wie ich es wollte:

    VB.NET-Quellcode

    1. Dim Ausgewaehlt As Boolean = False
    2. 'Wenn der entsprechende Menüpunkt bereits markiert ist, so wird dieser
    3. 'entmarkiert und das Dokubild wird deaktiviert.
    4. For Each Eintrag In DokuBilderMenue.DropDownItems
    5. If Eintrag.text <> "" Then
    6. If Eintrag.text = Sender.ToString Then
    7. Ausgewaehlt = Eintrag.Checked
    8. End If
    9. End If
    10. Next
    11. 'Wenn der Menüeintrag deaktiviert ist, wird die Funktion verlassen.
    12. If Not Ausgewaehlt Then
    13. DokubildAktiviert = False
    14. Exit Sub
    15. End If
    16. 'Jetzt kommt der Code, falls der Menüpunkt aktiviert ist.
    17. '.....


    Kann mir jemand den Unterschied zwischen "Option strict on" und "off" erklären?

    Früher hatte ich beispielsweise folgende Zeile verwendet:

    VB.NET-Quellcode

    1. X = X + 1


    Irgend wann hat das nicht mehr funktioniert und ich mußte dann Folgendes schreiben:

    VB.NET-Quellcode

    1. X += 1


    Hat das was damit zu tun?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „tron25“ ()

    tron25 schrieb:

    Irgend wann hat das nicht mehr funktioniert
    What :?:
    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!

    tron25 schrieb:

    Früher hatte ich beispielsweise folgende Zeile verwendet:
    VB.NET-Quellcode
    X = X + 1

    Irgend wann hat das nicht mehr funktioniert und ich mußte dann Folgendes schreiben:
    VB.NET-Quellcode
    X += 1

    Das ist ein Vergleich zwischen Äpfeln und Glühbirnen.
    X = X + 1 funktioniert noch immer. VS macht Dir nur den Vorschlag, es durch die sog. Verbundzuweisung zu kürzen.
    Option Strict On ist ausführlich im von @Akanel geposteten Link als auch in dem von mir in Post#2 geschriebenen erklärt inkl. Fortführungen der empfohlenen VS-Einstellungen. Daher ist es unnötig, hier noch was dazu zu schreiben.
    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.
    Ich habe mir den Inhalt des Links angeschaut und angefangen, die entsprechenden Fehlermeldungen auszubügeln. So habe ich beispielsweise folgendes geändert:

    VB.NET-Quellcode

    1. 'Alte Version
    2. Public Function Write(Data As String)
    3. '...
    4. Return True
    5. End Function
    6. 'Neue Version
    7. Public Function Write(Data As String) As Boolean
    8. '...
    9. Return True
    10. End Function


    Ich habe den Artikel so verstanden, das für jede Variable, jede Funktion und jede Methode ein Typ angegeben werden muß.

    Bei einigen Punkten komme ich nicht weiter.
    Beispiel 1:

    VB.NET-Quellcode

    1. My.Computer.FileSystem.DeleteDirectory(SlideshowVerzeichnis, True)
    2. 'Fehlermeldung:
    3. '"Option Strict On" lässt keine impliziten Konvertierungen von "Boolean" in "DeleteDirectoryOption" zu.


    Beispiel 2:

    VB.NET-Quellcode

    1. Public Sub PunktbildImportieren(Datei As String, Absender As String
    2. 'Die Funktion "Aufteilen" wird mit der Variablen "AktuelleZeile" aufgerufen.
    3. 'Sie schreibt seine Ergebnisse in das Array "Abschnitt".
    4. Dim AktuelleZeile as string
    5. Dim Abschnitt(2) As String
    6. Abschnitt = Aufteilen(AktuelleZeile)
    7. '...
    8. End sub
    9. Private Function Aufteilen(Zeile As String) As Array
    10. Dim X as Integer
    11. Dim Ergebnisse(2) As String
    12. X = 0
    13. Do Until X &gt;= Zeile.Length
    14. 'Jetzt wird der String überprüft. Je nach dem Ergebnis werden "Ergebnisse(0)", "Ergebnisse(1)" und "Ergebnisse(2)" entsprechend gefüllt.
    15. '...
    16. Loop
    17. Return Ergebnisse
    18. End Function
    19. 'Fehlermeldung:
    20. '"Option Strict On" lässt keine impliziten Konvertierungen von "Array" in "String()" zu.


    "Abschnitt" und "Ergebnisse" sind doch Array. Daher ist doch auch der Rückgabewert der Funktion ein Array - oder habe ich da einen Knick in der Optik?

    Die folgende Zeile wird markiert:

    VB.NET-Quellcode

    1. Abschnitt = Aufteilen(AktuelleZeile)

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

    Also ist eine Sub das Gleiche, wie eine Function, außer dass diese einen Rückgabewert hat. Sie sind beide Methoden. Ich gebe zu, dass ich bezüglich der Korrekten Bezeichnungen noch etwas Nachholbedarf habe. Danke für den Link.

    Für mein Beispiel bedeutet das:

    VB.NET-Quellcode

    1. Private Function Aufteilen(Zeile As String) As String()


    Ich habe es so verstanden, das ein Array, welches mit Zeichenketten gefüllt ist, eigendlich ein String() ist.

    Aber zu meinem ersten Beispiel habe ich leider keine Lösung gefunden. Wo könnte da das Problem liegen?