In einer kleinen Applikation mit NotifyIcon in der Taskbar wollte ich unterschiedliche ContextMenues öffnen, je nachdem, ob man mit der linken oder rechten Maustaste auf das Icon klickt.
Die erste Hürde, welche es zu nehmen gilt, ist es, dass ContextMenü auch bei einem Links-Klick zu öffnen. Man kann zwar eine entsprechende Methode nutzen, jedoch gibt es damit Probleme. Daher sollte man hier Reflection nutzen:
// constructor.. this._trayIcon.MouseDown += this.TrayIconMouseDown; private void TrayIconMouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { MethodInfo mi = typeof (NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic); mi.Invoke(this._trayIcon, null); } }
Nun öffnet sich schon mal das Kontextmenü auch beim Linksklick. Und hier kann man ansetzen, um das Menü entweder zu manipulieren oder zu ersetzen. Ich selbst habe mir einfach zwei Objekte vorbereitet, welche ich je nach Mausklick austausche:
private void TrayIconMouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this._trayIcon.ContextMenu = this._leftClickMenu; MethodInfo mi = typeof (NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic); mi.Invoke(this._trayIcon, null); } else if (e.Button == MouseButtons.Right) { this._trayIcon.ContextMenu = this._rightClickMenu; MethodInfo mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic); mi.Invoke(this._trayIcon, null); } }
Beim Testen ist mir aufgefallen, dass es mehrere Events gibt, an die man sich hängen könnte, etwa „MouseUp“, „MouseClick“ usw. Beim Testen hat bei mir allerdings nur „MouseDown“ korrekt funktioniert, bei den anderen hatte ich das Problem, dass zum Teil das Menü erst angezeigt wurde und dann der Eventhandler durchlaufen wurde (ich glaube sogar immer, wenn ich mit der linken Maustaste geklickt habe). Erklären konnte ich es mir allerdings nicht.