How do I make my WPF Context Menu go away when the user clicks outside the menu?
Asked Answered
G

2

9

First, the standard info:

VS2010 Ultimate
Win7 Ultimate x64
WPF app

The WPF context menu:

    <ContextMenu x:Key="RightClickSystemTray" Placement="MousePoint">
        <MenuItem Header="Exit" Click="Menu_Exit"></MenuItem>
    </ContextMenu>

The code to show it:

    void _notifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            ContextMenu menu = (ContextMenu)this.FindResource("RightClickSystemTray");
            menu.IsOpen = true;
        }
    }

The context menu is a WPF ContextMenu built in XAML. The notify icon in the system tray is a Forms notify icon (I don't know of a native WPF notify icon). Therefore, the notifyicon.ContextMenu property is not used. The code above works fine. When the user right clicks on the notify icon, the context menu shows as it should.

The issue I'm having is with making the ContextMenu go away when I want. It goes away fine as long as you click somewhere within the WPF app. This behavior is automatic. But if the user clicks elsewhere, such as the taskbar, the menu doesn't disappear. "LostFocus" events don't fire because these types of events only fire when an element loses focus to another element within the same app. As far as the app is concerned, the ContextMenu never loses focus. "Deactivated" was another event I tried to use. I should clarify at this point that the application has a "close to tray" option, so the application could close and fire the deactivated event before the user has a chance to right click and show the menu. The app is not reactivated when the menu appears, so the deactivated even won't fire when I click on the taskbar.

So finally, the question. How do I get my context menu to disappear when the user clicks away from it, even if the place where the user clicks isn't in the application that created the context menu?

Gouty answered 4/4, 2011 at 3:9 Comment(0)
S
0

I do not know if this is a viable option but if you switched to this library you'll have a well integrated tray-icon for WPF without such issues (there is sample code there for ContextMenus as well)

Stricklin answered 4/4, 2011 at 3:36 Comment(0)
C
0

What I did to fix this was simply to activate the mainWindow when the menu is opened.

Adding this.Activate() activates the mainWindow after the context menu has been opened so that when the mainWindow is de-activated(clicked outside of) it automatically sets the NotifyIcon's ContextMenu's IsOpen property to false.

My project was a C# WPF, .NET Framework3.5 project.

void _notifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
     if (e.Button == System.Windows.Forms.MouseButtons.Right)
     {
         ContextMenu menu =(ContextMenu)this.FindResource("RightClickSystemTray");
         menu.IsOpen = true;

         // this activates the mainWindow so that when it's de-activated(clicked outside of) it automatically sets the NotifyIcon's ContextMenu's IsOpen property to false
         this.Activate();
     }
}
Conference answered 10/7 at 5:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.