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
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();
}
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
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);
}
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
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.
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.
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
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...
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.
> Codejunky <
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
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
> Codejunky <
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 🙁
Hallo Rodney,
vermutlich hast du nicht alle nötigen Referenzen und usings hinzugefügt.
herbivore
mh ich hab mich undeutlich ausgedrückt, der Reflection-Aufruf klappt, aber danach findet er die ShowContextMenu-Methode immer noch nicht...
Hallo Rodney,
mh ich hab mich undeutlich ausgedrückt,
in der Tat. Siehe [Hinweis] Wie poste ich richtig? Punkt 5.
herbivore
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
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
Vielen Dank Herbivore, ich hatte mal wieder ein Brett vor dem Kopf 🤔