Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
ContextMenüStrip mit zweiter Ebene
Theki
myCSharp.de - Member



Dabei seit:
Beiträge: 55

Themenstarter:

ContextMenüStrip mit zweiter Ebene

beantworten | zitieren | melden

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?
private Nachricht | Beiträge des Benutzers
inflames2k
myCSharp.de - Experte

Avatar #AARsmmPEUMee0tQa2JoB.png


Dabei seit:
Beiträge: 2.296

beantworten | zitieren | melden

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 | Spielkartenbibliothek
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4.317

beantworten | zitieren | melden

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)?
private Nachricht | Beiträge des Benutzers
Theki
myCSharp.de - Member



Dabei seit:
Beiträge: 55

Themenstarter:

beantworten | zitieren | melden

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));
        }
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Theki am .
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Theki,
Zitat
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
private Nachricht | Beiträge des Benutzers
Theki
myCSharp.de - Member



Dabei seit:
Beiträge: 55

Themenstarter:

beantworten | zitieren | melden

Zitat von herbivore
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.
private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5.299

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Theki
myCSharp.de - Member



Dabei seit:
Beiträge: 55

Themenstarter:

beantworten | zitieren | melden

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);

private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5.299

beantworten | zitieren | melden

[Hinweis] Wie poste ich richtig? , Pkt 5
Der frühe Apfel fängt den Wurm.
private Nachricht | Beiträge des Benutzers
Theki
myCSharp.de - Member



Dabei seit:
Beiträge: 55

Themenstarter:

beantworten | zitieren | melden

Ups, sry vergessen
Zitat
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.
private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5.299

beantworten | zitieren | melden

hat mich eh gewundert, dass du sender auf ContextmenuStrip castest. Hätte erwartet, dass der sender ein ToolStripMenuItem ist.
Ja, und wenn der Fehler sagt "ContextmenuStrip" hat keine Owner-Property, dann stimmt das wohl
Der frühe Apfel fängt den Wurm.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Theki,
Zitat von Theki
Zitat von herbivore
Wodurch wird das Kontextmenu angezeigt?

Durch den Rechtsklick auf ein Label.
ich meinte natürlich welcher Code dafür verantwortlich ist.

herbivore
private Nachricht | Beiträge des Benutzers
Theki
myCSharp.de - Member



Dabei seit:
Beiträge: 55

Themenstarter:

beantworten | zitieren | melden

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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Theki am .
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4.317

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Theki
myCSharp.de - Member



Dabei seit:
Beiträge: 55

Themenstarter:

beantworten | zitieren | melden

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;
        }
private Nachricht | Beiträge des Benutzers
Theki
myCSharp.de - Member



Dabei seit:
Beiträge: 55

Themenstarter:

beantworten | zitieren | melden

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?
private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5.299

beantworten | zitieren | melden

Zitat von Theki
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.
private Nachricht | Beiträge des Benutzers
Theki
myCSharp.de - Member



Dabei seit:
Beiträge: 55

Themenstarter:

beantworten | zitieren | melden

Ü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.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Theki,
Zitat
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
private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5.299

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Theki
myCSharp.de - Member



Dabei seit:
Beiträge: 55

Themenstarter:

beantworten | zitieren | melden

Zitat von ErfinderDesRades
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.
private Nachricht | Beiträge des Benutzers
ErfinderDesRades
myCSharp.de - Experte

Avatar #avatar-3151.jpg


Dabei seit:
Beiträge: 5.299

beantworten | zitieren | melden

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 toolstripmenuItem. )
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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von ErfinderDesRades am .
Der frühe Apfel fängt den Wurm.
private Nachricht | Beiträge des Benutzers