I want to have it such that left clicking on the NotifyIcon also causes the context menu (set with the ContextMenuStrip property) to open as well. How would I achieve this?
You would normally handle the MouseClick event to detect the click and call the ContextMenuStrip.Show() method:
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) {
contextMenuStrip1.Show(Control.MousePosition);
}
But that doesn't actually work properly, the CMS won't close when you click outside of it. Underlying issue is a Windows quirk (aka "bug") that is described in this KB article.
Invoking this workaround in your own code is pretty painful, the pinvoke is unpleasant. The NotifyIcon class has this workaround in its ShowContextMenu() method, they just made it difficult to get to since it is a private method. Reflection can bypass that restriction. I discovered this hack 5 years ago and nobody reported a problem with it yet. Set the NFI's ContextMenuStrip property and implement the MouseUp event like this:
using System.Reflection;
...
private void notifyIcon1_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
MethodInfo mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic);
mi.Invoke(notifyIcon1, null);
}
}
use the following code to show context menu on both right and left click on notifyicon, if you find any issue then text me at arshad_mcs786@hotmail.com (arshad from Islamabd)
//System.Runtime.InteropServices use thi as reference
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool SetForegroundWindow(HandleRef hWnd);
private void notifyIcon1_Click(object sender, EventArgs e)
{
SetForegroundWindow(new HandleRef(this, this.Handle));
int x = Control.MousePosition.X;
int y = Control.MousePosition.Y;
x = x - 10;
y = y - 40;
this.contextMenuStrip1.Show(x,y );
//this.PointToClient(Cursor.Position)
}
You can wire in a onClick event for notify icon then call show in the on click
private void wire()
{
notifyIcon1.Click += new EventHandler(notifyIcon1_Click);
}
void notifyIcon1_Click(object sender, EventArgs e)
{
contextMenuStrip1.Show(Cursor.Position);
}
If you handle MouseUp rather than Click, you will be able to tell which button was clicked, as well as the location of the click. You can use this location as the location to show the ContextMenu
notifyIcon.MouseUp += new MouseEventHandler(delegate(object sender, MouseEventArgs e) { contextMenu.Show(e.Location); });