Laden...

ContextMenu bei Linksklick auf NotifyIcon anzeigen

Erstellt von herbivore vor 19 Jahren Letzter Beitrag vor 16 Jahren 8.710 Views
herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 19 Jahren
ContextMenu bei Linksklick auf NotifyIcon anzeigen

Hallo Community,

ich möchte dass das ContextMenu meines NotifyIcons auch bei Linksklick angezeigt wird. Man kann ein Kontextmenü zwar manuell mit Show anzeigen, aber als ersten Parameter will Show ein Control. Ein Control habe ich aber nicht, es gibt nur das NotifyIcon (erbt von Component und nicht von Control) und das ContextMenu. Selbst ein Dummy-Control zu erzeugen, nützt nichts: "System.ArgumentException: ContextMenu cannot be shown on an invisible control."

Ich kenne aber NotifyIcons, die auf Linksklick ein Contextmenü anzeigen. Wie kriege ich das hin?

Vielen Dank!

herbivore

137 Beiträge seit 2005
vor 19 Jahren

Seltsam. Ich vermute Du hast es auf diese Weise versucht und erhälst eine Exception, da (wie Du schon geschrieben hast) ein NotifyIcon nicht von Control abstimmt:

private void notifyIcon_Click(object sender, EventArgs e)
{
    this.ContextMenuStrip.Show();
}

Dann erkläre mir mal wieso es auf diesem Weg funktioniert: 😁

private void notifyIcon_Click(object sender, EventArgs e)
{
    this.notifyIcon.ContextMenuStrip.Show();
}
herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 19 Jahren

Hallo Shaderman,

vielen Dank! Leider ich benutze ich nicht ContextMenuStrip sondern ein "normales" ContextMenu. Ein kurzer Blick in die Doku und auf ein eilends erzeugtes ContextMenuStrip halten mich auch davon ab, dies zu benutzen. Und bei ContextMenu gibt es kein parameterloses Show.

herbivore

A
154 Beiträge seit 2005
vor 19 Jahren

durch rumprobieren bin ich auf folgende Lösung gekommen.


private void notifyIcon1_Click(object sender, System.EventArgs e)
{
	Point pointScreen = new Point();
	pointScreen.X = System.Windows.Forms.Cursor.Position.X ;
	pointScreen.Y = System.Windows.Forms.Cursor.Position.Y ;
			
	Point pointClient = this.PointToClient(pointScreen);
	this.contextMenu1.Show(this,pointClient);			
}	

herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 19 Jahren

Hallo AlfameisterT,

vielen Dank für Deine Mühe. Die spannende Frage ist, was ist bei Dir this?

Ich habe kein Form, nur das ContextMenu (und das NotifyIcon). Alle meine Methoden sind static-Methoden der abstakten Klasse, in der sich auch Main befindet.

herbivore

A
154 Beiträge seit 2005
vor 19 Jahren

Hmm, ein Form natürlich 😁

Hab ich wohl überlesen.

Ich habs grad mal in ner Consolen Anwendung versucht. Irgendwie schmeißt das Icon kein Event.

Ein dummy Control kannst du mit "CreateControl()" erstellen. Dann ist das auch da. Nur mit den Koordinaten will das irgendwie nicht.

herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 19 Jahren

Hallo AlfameisterT,

mit deinem Code in Verbindung mit einem Dummy-Control, auf das ich CreateControl anwende, funktioniert es jetzt. Vielen Dank!

Das ist zwar von hinten durch die Brust ins Auge, aber dafür kannst du ja nichts.

Was die "Consolen"-Anwendung angeht: In Tab Control kannst du sehen, wie die Struktur meiner Anwendung aussieht. Allerdings übersetze ich sie schon als /target:winexe.

herbivore

PS: Leider verschwindet das mit der linken Maustaste angezeigte Menü nicht so zuverlässig, wenn man außerhalb klickt. Wenn man es mit der rechte Maustaste geöffnet hat, kann man es mit außerhalb Klicken immer schließen.

herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 19 Jahren

Hallo zusammen,

Dass das Menü nicht zuvelässig verschwindet hat mir keine Ruhe gelassen und ich habe jetzt die ultimative Lösung, die sogar ganz ohne Dummy-Control auskommt.

NotifyIcon hat eine parameterlose Methode ShowContextMenu, mit der man das eingetragene Kontextmenü anzeigen kann. Der einzige Haken ist, dass die Methode (aus mir unerfindlichen Gründen) private ist. Das ist aber in .NET dank Reflection ja keine wirkliche Klippe:


notico.GetType ().InvokeMember ("ShowContextMenu", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, notico, null);

herbivore

369 Beiträge seit 2006
vor 17 Jahren

Original von herbivore
Hallo zusammen,

Dass das Menü nicht zuvelässig verschwindet hat mir keine Ruhe gelassen und ich habe jetzt die ultimative Lösung, die sogar ganz ohne Dummy-Control auskommt.

NotifyIcon hat eine parameterlose Methode ShowContextMenu, mit der man das eingetragene Kontextmenü anzeigen kann. Der einzige Haken ist, dass die Methode (aus mir unerfindlichen Gründen) private ist. Das ist aber in .NET dank Reflection ja keine wirkliche Klippe:

  
notico.GetType ().InvokeMember ("ShowContextMenu", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, notico, null);  
  

herbivore

Bei solchen Punkten solltest du darüber nachdenken dich bei connect.microsoft.com zu registrieren und die Vorteile einer Veröffentlichung dieser Methode als Vorschlag einbringen. Nur durch Feedback an MS kann sich in den nächsten Versionen etwas ändern...

1.665 Beiträge seit 2006
vor 17 Jahren

Hi herbivore,

Darf ich mal fragen wieso du kein ContextMenuStrip benutzt? Das interessiert mich wegen deiner Aussage

Original von herbivore
Ein kurzer Blick in die Doku und auf ein eilends erzeugtes ContextMenuStrip halten mich auch davon ab, dies zu benutzen.

herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Kabelsalat,

Nur durch Feedback an MS kann sich in den nächsten Versionen etwas ändern...

da hast du sicher recht. Mein Support für Microsoft-Produkte beschränkt sich jedoch auf Hilfeleistung in diesem Forum. Ich vertraue darauf, dass andere Leute ihre Freizeit auf andere Schwerpunkte konzentrieren. So wird es sicher eine Menge Leute geben, die für das Feedback an Microsoft sorgen. Vielleicht sogar jemand, der diesen Beitrag liest und sowieso schon bei connect.microsoft.com registriert ist.

Hallo JunkyXL,

Darf ich mal fragen wieso du kein ContextMenuStrip benutzt?

ja, fragen kannst du das schon, aber ich hoffe, du erwartest nicht, dass ich mich da nach gut 1 1/2 Jahren da noch erinnere, was mich damals im einzelnen bewogen hat. 🙂 Ich kann nur vermuten, dass ich das "gewohnte" Aussehen des Kontextmenüs haben wollte. Worauf sich der Hinweis mit der Doku bezieht, weiß ich nicht mehr.

herbivore

1.665 Beiträge seit 2006
vor 17 Jahren

Zufälligerweise verwende ich in meinem Programm jetzt auch ein ContextMenu, allerdings wird es ganz unten rechts in der Ecke des Bildschirms angezeigt, obwohl laut Koordinaten es da nicht sein sollte, und es ist an ein Control attached ist, was sich dort auch niemals befindet.

Ich verstehe das nicht. Habe als Point sogar die MousePosition dafür angewendet...
Das Ganze geschieht nämlich auf einer Form.

contextMenu.Show(this.buttonXy, MousePosition, LeftRightAlignment.Left);

Danke schonmal für Tipps

R
341 Beiträge seit 2004
vor 16 Jahren

Original von herbivore
Hallo zusammen,

Dass das Menü nicht zuvelässig verschwindet hat mir keine Ruhe gelassen und ich habe jetzt die ultimative Lösung, die sogar ganz ohne Dummy-Control auskommt.

NotifyIcon hat eine parameterlose Methode ShowContextMenu, mit der man das eingetragene Kontextmenü anzeigen kann. Der einzige Haken ist, dass die Methode (aus mir unerfindlichen Gründen) private ist. Das ist aber in .NET dank Reflection ja keine wirkliche Klippe:

  
notico.GetType ().InvokeMember ("ShowContextMenu", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, notico, null);  
  

herbivore

Ich kram den Thread mal wieder heraus, weil ich momentan genau dasselbe Problem habe: Ein TrayIcon was 2 ein ContextMenu beim Linkslklick anzeigen soll.
Wenn ich die private Methode mit deinem Code public mache, wie greife ich danach darauf zu? Beim kompilieren meckert er ja, dass er die Methode nicht kennt 🙁

herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Rodney,

vermutlich hast du nicht alle nötigen Referenzen und usings hinzugefügt.

herbivore

R
341 Beiträge seit 2004
vor 16 Jahren

mh ich hab mich undeutlich ausgedrückt, der Reflection-Aufruf klappt, aber danach findet er die ShowContextMenu-Methode immer noch nicht...

herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Rodney,

mh ich hab mich undeutlich ausgedrückt,

in der Tat. Siehe [Hinweis] Wie poste ich richtig? Punkt 5.

herbivore

R
341 Beiträge seit 2004
vor 16 Jahren

trayIcon.GetType().InvokeMember("ShowContextMenu", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, trayIcon, null);

trayIcon.ShowContextMenu();

Fehlermeldung:

Error 2 'System.Windows.Forms.NotifyIcon' does not contain a definition for 'ShowContextMenu'

Gruß, Rodney

herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Rodney,

die Methode ShowContextMenu wird durch die Zeile

notico.GetType ().InvokeMember ("ShowContextMenu", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, notico, null);

aufgerufen (InvokeMember = rufe Member (=Methode) auf), weil man sie eben nicht direkt mit

trayIcon.ShowContextMenu();

aufrufen kann.

herbivore

R
341 Beiträge seit 2004
vor 16 Jahren

Vielen Dank Herbivore, ich hatte mal wieder ein Brett vor dem Kopf 🤔