Laden...

ContextMenüStrip mit zweiter Ebene

Erstellt von Theki vor 14 Jahren Letzter Beitrag vor 13 Jahren 5.797 Views
T
Theki Themenstarter:in
55 Beiträge seit 2009
vor 14 Jahren
ContextMenüStrip mit zweiter Ebene

Hi zusammen,

ich grübel im Moment vor einem Problem.
Mein ContextmenüStrip ist so aufgebaut.

-Auswahl 1
-> Punkt 1
-> Punkt 2
-> Punkt 3
-Auswahl 2
-> Punkt 4
...

Wenn ich nun z.b. auf Punkt 2 klicke möchte ich herausfinden von dem dies ausging. In meinem Fall alles Label's.
Für die Aktion bei "Auswahl 1" ist dies kein Problem, die löse ich wie folgt:


(contextMenuStrip2.SourceControl as Label).Text

So doch wie mach ich das für z.b. den Punkt 1.
Wie oben scheint es nich zugeben.
Ich habe schon mal gegoogelt, dies soll wohl ein Bug beim Framework sein.

Kennt jmd eine einfache Lösung?

2.298 Beiträge seit 2010
vor 14 Jahren

Du hast also ein ClickEvent?


ToolStripMenuItem it = (ToolStripMenuItem)sender;

Ansonsten sollte es so ja nicht mehr all zu sehr kompliziert sein.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

4.931 Beiträge seit 2008
vor 14 Jahren

Hallo Theki,

was steht denn dann im contextMenuStrip2.SourceControl drin (null)?
Wo hast du denn von diesem Bug gelesen? Und welche .NET-Version benutzt du (evtl. hilft ja ein Update)?

T
Theki Themenstarter:in
55 Beiträge seit 2009
vor 14 Jahren

Genau er gibt als Fehler zurück beim Debuggen:

Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.

Folglich ist contextMenuStrip2.SourceControl = null.

Puh find den Link nicht mehr, wo ich das gelesen hab.
Also Entwicklungsumgebung nutz ich VS 2009 prof mit .net 3.5.
Hab es aber auch unter VS 2010 mit .net 4.0 probiert, wo es nach meinem Muster nicht geht.

Edit:
Im Moment sieht der Code wie folgt aus:


        private void test2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(Convert.ToString((contextMenuStrip2.SourceControl as Label).Text));
        }

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Theki,

Folglich ist contextMenuStrip2.SourceControl = null.

... oder kein Label.

Im Allgemeinen siehe [FAQ] NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt [finden und beheben]

Wodurch wird das Kontextmenu angezeigt?

BTW: Das Convert.ToString ist überflüssig und solltest du daher entfernen.

herbivore

T
Theki Themenstarter:in
55 Beiträge seit 2009
vor 14 Jahren

Wodurch wird das Kontextmenu angezeigt?

Durch den Rechtsklick auf ein Label.
Bei einem Menüstrip "erster Ordnung" funktioniert es ja, nur nicht bei der 2. ordnung.

5.299 Beiträge seit 2008
vor 14 Jahren

und wenn du weißt, dasses ein Item 2. Ordnung ist, kann man da nicht den Parent von rauskriegen?

(edit: kann auch Owner heißen)

Der frühe Apfel fängt den Wurm.

T
Theki Themenstarter:in
55 Beiträge seit 2009
vor 14 Jahren

Davon hatte ich auch schon gelesen, hast du da nen Lösungsansatz für mich?

Hab an sowas gedacht, aber das geht nicht:



            ContextMenuStrip tsItem = (ContextMenuStrip)sender;
            ContextMenuStrip cMenuStrip = (ContextMenuStrip)tsItem.Owner;
            MessageBox.Show((cMenuStrip.SourceControl as Label).Text);


5.299 Beiträge seit 2008
vor 14 Jahren

Der frühe Apfel fängt den Wurm.

T
Theki Themenstarter:in
55 Beiträge seit 2009
vor 14 Jahren

Ups, sry vergessen

Fehler 1 "System.Windows.Forms.ContextMenuStrip" enthält keine Definition für "Owner", und es konnte keine Erweiterungsmethode "Owner" gefunden werden, die ein erstes Argument vom Typ "System.Windows.Forms.ContextMenuStrip" akzeptiert. (Fehlt eine Using-Direktive oder ein Assemblyverweis?)

Ich versteh einfach nich, dass es keine leichte Lösung dafür gibt.

5.299 Beiträge seit 2008
vor 14 Jahren

hat mich eh gewundert, dass du sender auf ContextmenuStrip castest. Hätte erwartet, dass der sender ein ToolStripMenu_Item_ ist.
Ja, und wenn der Fehler sagt "ContextmenuStrip" hat keine Owner-Property, dann stimmt das wohl

Der frühe Apfel fängt den Wurm.

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Theki,

Wodurch wird das Kontextmenu angezeigt?

Durch den Rechtsklick auf ein Label.

ich meinte natürlich welcher Code dafür verantwortlich ist.

herbivore

T
Theki Themenstarter:in
55 Beiträge seit 2009
vor 14 Jahren

Versteh nich was du meinst, hab es über die Eigenschaft-Übersicht an das Label angebunden.
Hab grade mal den Degsiner aufgerufen, da steht follgendes:


            // 
            // label1
            // 
            this.label1.ContextMenuStrip = this.contextMenuStrip2;
            // 
            // contextMenuStrip2
            // 
            this.contextMenuStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.test1ToolStripMenuItem});
            this.contextMenuStrip2.Name = "contextMenuStrip2";
            this.contextMenuStrip2.Size = new System.Drawing.Size(153, 48);
            // 
            // test1ToolStripMenuItem
            // 
            this.test1ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.test2ToolStripMenuItem});
            this.test1ToolStripMenuItem.Name = "test1ToolStripMenuItem";
            this.test1ToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.test1ToolStripMenuItem.Text = "Test1";
            // 
            // test2ToolStripMenuItem
            // 
            this.test2ToolStripMenuItem.Name = "test2ToolStripMenuItem";
            this.test2ToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.test2ToolStripMenuItem.Text = "Test2";
            this.test2ToolStripMenuItem.Click += new System.EventHandler(this.test2ToolStripMenuItem_Click);

Sieht dann wie follgt aus:
-Test1
-> Test2

Ich hoffe, dass beantwortet deine Frage

4.931 Beiträge seit 2008
vor 14 Jahren

Der Bug scheint bei MS bekannt zu sein: https://connect.microsoft.com/VisualStudio/feedback/details/282496/contextmenustrip-sourcecontrol-always-returns-null-for-items-in-sub-menus

Und unter Workarounds steht auch die Alternative: merke dir im Opening- bzw. Opened-Event das SourceControl in einer Membervariablen (denn dort ist es richtig gesetzt) und benutze diese dann in dem Click-Event der Submenus.

T
Theki Themenstarter:in
55 Beiträge seit 2009
vor 14 Jahren

Danke, wunderbar 😃

Hier meine Lösung:


        Control rightClickedControl = null;
        private void test2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(rightClickedControl.Text);
        }

        private void contextMenuStrip2_Opening(object sender, CancelEventArgs e)
        {
            rightClickedControl = contextMenuStrip2.SourceControl;
        }

T
Theki Themenstarter:in
55 Beiträge seit 2009
vor 13 Jahren

Habe den Titel mal angepasst, da ich es unsinnig finde, einen neuen Post aufzumachen.

Ich beschäftige mich immer noch mit Contextmenütext mit "2 Ebenen":

-Test1
-> Test2
-> Test3
-> Test4

So nun habe ich in dem Tag's von (Test2,3 und 4 etc.) einen String hinterlegt.

Nun möchte ich dass bei jedem Click-Ereigniss auf den ToolStrip 2. Ordnung mir der Tag angezeigt wird


        private void test2ToolStripMenuItem1_Click(object sender, EventArgs e)
        {

        }

Dies ist ja nun normal über den "sender" möglich, doch wenn man diesen im Debugger betrachtet ist dieser Leer.

Braucht ihr mehr Code? Hat jemand von euch eine Idee wie man dies löst?

5.299 Beiträge seit 2008
vor 13 Jahren

Dies ist ja nun normal über den "sender" möglich, doch wenn man diesen im Debugger betrachtet ist dieser Leer.

Bei mir nicht (alles im Designer gemacht).

Der frühe Apfel fängt den Wurm.

T
Theki Themenstarter:in
55 Beiträge seit 2009
vor 13 Jahren

Über den Degsiner würde ich es ungern machen, weil ich ca. 20 ToolStrip's habe.
Ich würde gern die Click-Ereignisse alle auf einen legen und dann wie normal mit dem Sender arbeiten.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Theki,

Dies ist ja nun normal über den "sender" möglich, doch wenn man diesen im Debugger betrachtet ist dieser Leer. ... Hat jemand von euch eine Idee wie man dies löst?

die Antwort hat doch Th69 etwas weiter oben schon gegeben.

herbivore

5.299 Beiträge seit 2008
vor 13 Jahren

nee, das bezog sich auf die Owner-Property, die falsch zurückgegeben wird. Jetzt behauptet Theki, das sender-Argument im Click-Handler bleibe auch leer, was m.E. aber nicht stimmt, jedenfals kannichsnicht reproduzieren.

Der frühe Apfel fängt den Wurm.

T
Theki Themenstarter:in
55 Beiträge seit 2009
vor 13 Jahren

nee, das bezog sich auf die Owner-Property, die falsch zurückgegeben wird.

Ja genau danke.

Ich versuch es im moment mit follgendem Code:


        private void test2ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(Convert.ToString((sender as ToolStrip).Tag));
        }

So, wenn ich nun beim Debuggen in den lokalen Teil schaue, finde ich beim sender follgende Struktur:

sender -> base -> base

und erst in dem zweiten base, sind die Informationen drin, an die ich ran möchte.

I.wie hab ich im moment nen Brett vorm Kopf.

5.299 Beiträge seit 2008
vor 13 Jahren

du solltest vlt. den sender nicht auf toolstrip casten, sondern auf...

edit: oder anners: Der Debugger zeigt dir auch den correkten Datentypen von Sender an.
Das mit base->base... ist nicht eine Struktur von Objekten, sondern das bildet die Vererbung ab.
also der sender-typ erbt von einem andern, der wiederum von einem anderen erbt, der die Tag-Property bereitstellt.
also sender ist ein toolstripmenuItem (kann darauf gecastet werden). toolstripmenuItem erbt von ToolStripDropDownItem, somit ist sender also ein erweitertes ToolStripDropDownItem (nämlich ein toolstrip_menu_Item. )
ToolStripDropDownItem erbt von ToolStripItem (also _ist _sender ein erweitertes ToolStripItem ), und ToolStripItem hat die Tag-Property.
Du kannst sender also auf ToolStripItem , ToolstripDropDownItem oder auf ToolstripMenuItem casten - jedes ist eine Erweiterung der vorherigen, beinhaltet alle vorherigen Eigenschaften, inkl. die Tag-Prop.

Das sind aber basics von OOP, und du solltest dir wohl ein Buch dazu durcharbeiten.

mein bisheriges Lieblingsbuch ist VB2005 DasEntwicklerbuch, weil das sowohl ausführlich auf Vererbung eingeht, als auch auf die VS-IDE.
Kennte ich ein vergleichbares c#-buch, tätich das natürlich empfehlen

Der frühe Apfel fängt den Wurm.