none
MenuStrip / ContextMenuStrip schließen RRS feed

  • Frage

  • Hallo zusammen,

    sicher eine stupide Frage, aber ich muss sie trotzdem stellen:

    Ein MenuStrip soll beim Klick auf ein ToolStripMenuItem, welches allerdings "Childs" besitzt (.DropDownItems) geschlossen werden. Normalerweise schließt sich das Menu ja nur, wenn das geklickte ToolStripMenuItem selbst keine "Childs" mehr hat...

    Wie kann ich ihm beibringen, sich dennoch zu schließen? MenuStrip.close() oder ähnliches finde ich nicht, beim ContextMenuStrip scheint es ein.close() zu geben...

    Viele lieben Dank, Jan

    Mittwoch, 20. März 2013 15:50

Antworten

  • Hallo Jan,

    hast Du den "Nachtrag" schon ausprobiert?

    Wenn ich Deine Beschreibung richtig verstanden habe, sollte es  ohne Handstand gehen, wenn man in den Fällen, in denen es Unterkategorien gibt, als erstes Element ein Element wie "(Ohne)" aufnimmt, was dazu führt, dass der Auswahlvorgang bei der Kategorie beendet wird.

    Persönlich würde ich eher ein TreeView verwenden und im Formular platzieren - denn IMHO hat so etwas in Menüs nichts verloren - aber jeder nach seinem Gusto ;)

    Gruß Elmar

    • Als Antwort markiert Jan Kornblum Montag, 22. April 2013 11:09
    Freitag, 22. März 2013 17:09
    Beantworter

Alle Antworten

  • Hallo,

    ein Stück bin ich weiter, aber noch nicht ganz optimal:

    ToolStripMenuItem.HideDropDown()

    ...auf das "oberste" MenuItem angewandt, verbirgt zwar das Dropdown, jedoch ist das nicht gleichwertig einem "gewöhnlichen" Klick/Close, denn der MenuStrip an sich hat dann noch den Focus, und beim MouseOver klappen die anderen DropDowns natürlich, ohne dass ein MouseClick notwendig ist.

    Grüße, Jan

    Donnerstag, 21. März 2013 16:59
  • Hallo,

    Ich denke es reicht, wenn du die Gesamte Form neu fokussierst (Me.Fokus()).

    Das gesamte geöffnete Menü schließt sich dann.

    (Wenn ich das vielleicht soweit nicht richtig verstanden habe, einfach nocheinmal zurückschreiben ;) )

    Viel Glück

    Freitag, 22. März 2013 12:28
  • Hi pipsfux3000,

    danke, hat sich nach einer prima Idee angehört, klappt aber leider nicht. Solange man sich im aufgeklappten Menü befindet, bleibt ein Me.Focus() ohne jegliche Wirkung :(

    Grüße, Jan


    Freitag, 22. März 2013 15:16
  • Hallo Jan,

    mir ist unverständlich, was das Ganze bewirken soll. Wieso soll ein DropDown geschlossen werden, anstatt aufgeklappt? Faktisch widerspricht das der Menülogik - die seit Windows 95 (oder früher) gültig ist:

    Menüs werden durch Klick auf ein anderes Element oder über die Escape Taste geschlossen bzw. durch F10 / Alt-Taste das Fenstermenü aktiviert.

    Ein anderes Verhalten ist so ohne weiteres gar nicht zu bewerkstelligen. Denn während sich das Formular im "Menü-Modus" befindet, wird ein Meldungsfilter aktiviert, der Maus und Tastatur an die Menüelemente weiterleitet.

    Die ToolStripManager Klasse enthält dazu einige Methoden, die durchweg intern sind - von außen nicht zugänglich; so z. B. eine ExitMenuMode Methode.

    ToolStrip kennt die geschützte RestoreFocus-Methode, das nämliche Methode neben anderen aufruft. Um sie zu nutzen müsste man eine eigene Klasse ableiten.

    Einige kurze Versuche, die Methoden über Reflection aufzurufen hatten nicht den gewünschten Erfolg; wobei ich nicht weiß - siehe Eingangsabsatz -, wann das genau passieren soll.

    Kleiner Nachtrag:

    Über ein DoubleClick-Ereignis realisiert, funktioniert es in tieferen Ebenen, wenn man übergeordneten Ebenen schliesst:

        Private Sub mainMenuMenuItem_DoubleClick(sender As System.Object, e As System.EventArgs) _
            Handles mainMenu1ToolStripMenuItem.DoubleClick, _
            mainMenu12ToolStripMenuItem.DoubleClick
            ' Testhalber für 1. und 2. Ebene mit aktiviertem Doppelklick
            Dim menuItem = DirectCast(sender, ToolStripMenuItem)
            menuItem.HideDropDown()
            menuItem = DirectCast(menuItem.OwnerItem, ToolStripMenuItem)
            While menuItem IsNot Nothing
                menuItem.HideDropDown()
                menuItem = DirectCast(menuItem.OwnerItem, ToolStripMenuItem)
            End While
        End Sub
    
    Gruß Elmar
    Freitag, 22. März 2013 16:09
    Beantworter
  • Hi Elmar,

    ja, es ist ein ungewöhnlicher Fall, ich erkläre es kurz:

    In dem Menü sind sozusagen "verschachtelte Kategorien" untergebracht (Die Kategorien losgelöst vom Menü stehen dabei in eine Parent-Child Relation zu sich selbst). Die verschachtelten Kategorie-Objekte werden in einer rekursiven Methode durchlaufen und so das Menü generiert. Dabei wird im ToolStripMenuItem.Tag jeweils das Kategorie-Objekt gespeichert.

    Über das Menü soll diese Verschachtelung für den User also dargestellt werden, mit der Möglichkeit, dass eben auch eine Kategorie (ToolSTripMenuItem), die beliebig viele Unterkategorien haben kann, "angeklickt" werden kann und nicht nur eine Kategorie, die selbst keine Unterkategorien (.DropDownItems) hat.

    Im Click()-Event des jeweiligen ToolStripMenuItems wird dann weiterer Code ausgeführt und über CType(CType(sender, ToolStripMenuItem).Tag, Catgegory) kann auf die Kategorie zugegriffen werden...

    Du meinst also, ein solcher "Mißbrauch" der MenuStrip ist einfach nciht machtbar? Es funktioniert ja, hat nur einen Schönheitsfehler. Beim ContextMenuStrip im Gegensatz zum verwendeten MenuStrip ist das Schließen des Menü problemlos über eine .Close() Methode möglich...

    Grüße, Jan

    Freitag, 22. März 2013 16:40
  • Hallo Jan,

    hast Du den "Nachtrag" schon ausprobiert?

    Wenn ich Deine Beschreibung richtig verstanden habe, sollte es  ohne Handstand gehen, wenn man in den Fällen, in denen es Unterkategorien gibt, als erstes Element ein Element wie "(Ohne)" aufnimmt, was dazu führt, dass der Auswahlvorgang bei der Kategorie beendet wird.

    Persönlich würde ich eher ein TreeView verwenden und im Formular platzieren - denn IMHO hat so etwas in Menüs nichts verloren - aber jeder nach seinem Gusto ;)

    Gruß Elmar

    • Als Antwort markiert Jan Kornblum Montag, 22. April 2013 11:09
    Freitag, 22. März 2013 17:09
    Beantworter
  • Hi Elmar,

    komme leider erst jetzt dazu, zu antworten. Deinen "Nachtrag" habe ich noch nicht ausprobiert, werde das gleich mal nachholen.

    Die Alternative mit dem "Ohne"-Eintrag wäre als Workaround auch denkbar.

    Die TreeView-Variante wäre natürlich das Mittel meiner Wahl (kommt auch bei der Detailansicht bereits zum Einsatz), jedoch scheidet diese im konkreten Fall aus Platzgründen aus, habe hier nur ca 1cm Höhe zur Verfügung ;)

    Grüße, Jan


    Mittwoch, 27. März 2013 15:56
  • Hi Elmar, nochmal,

    deinen Nachtrag mit dem "HideDropDown()" habe ich bereits im Einsatz, sogar beim .Click-Event, jedoch auf nicht nur auf einzelne untergeordnete MenuItems angewandt, sondern auf den TopLevel MenuStripItem.

    Funktioniert, hat nur den Schönheitsfehler, dass der gesamte MenüStrip noch "aktiv" leibt, sprich, Menü öffnet sich erneut beim MouseOver, ohne dass ein Klick (wie sonst) notwendig ist. Ein .select() oder .focus() auf ein beliebiges anderes Steuerelement ändert daran auch nicht...

    Mittwoch, 27. März 2013 16:11
  • Hi Elmar,

    habe es nun wirklich so umgesetzt, dass Kategorien *mit* Unterkategorien in Ihrem Level selbst nicht direkt anklickbar sind, dass sie jedoch in der Ebene tiefer nochmal als erstes Item ohne ihre Unterkategorien mit nachfolgendem Separator auftauchen. Ist prima so ;)

    Grüße, Jan

    Montag, 22. April 2013 11:09