简体   繁体   中英

How to use a WPF ContextMenu with NotifyIcon

I want to open a WPF ContextMenu when the user clicks the system tray icon. With Windows Forms this is straight-forward, just call notifyIcon.ContextMenu = contextMenu and you're set.

On WPF we can not set the ContextMenu that easily because WPF's ContextMenu class is not related to Forms ContextMenu. The alternative I have been pursuing is to handle NotifyIcon's Click event to open the WPF-style ContextMenu.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // This is intended to be a system tray application so we hide the window
        this.Visibility = Visibility.Hidden;

        // Winform context menu
        // The context menu closes when the user clicks anywhere outside the menu
        // The user can navigate the menu with the keyboard arrows and close with ESC
        var notifyIcon1 = new System.Windows.Forms.NotifyIcon();
        var contextMenu = new System.Windows.Forms.ContextMenu();
        var menuItem = new System.Windows.Forms.MenuItem();
        menuItem.Text = "WinForm Menu Item";
        contextMenu.MenuItems.Add(menuItem);
        notifyIcon1.ContextMenu = contextMenu;
        notifyIcon1.Icon = Properties.Resources.ico;
        notifyIcon1.Visible = true;

        // WPF context menu
        // The user cannot close the menu by clicking outside its bounds
        // Does not detect any keyboard input
        var notifyIcon2 = new System.Windows.Forms.NotifyIcon();
        notifyIcon2.Icon = Properties.Resources.ico;
        notifyIcon2.Visible = true;
        notifyIcon2.Click += NotifyIcon2_Click;
    }

    private void NotifyIcon2_Click(object sender, EventArgs e)
    {
        var contextMenu = new ContextMenu();
        var menuItem = new MenuItem();
        menuItem.Header = "WPF Menu Item";
        contextMenu.Items.Add(menuItem);
        contextMenu.IsOpen = true;
    }
}

The issue with this approach is that the WPF ContextMenu never gets any hint that the user has navigated away from the menu and should close (Eg, when the user clicks outside the bounds of the menu). None of the Focus or MouseCapture events are ever triggered and I am unable to close the menu other than by clicking on one of its items.

So the question here, to put slightly different, is: how do I properly emulate the NotifyIcon's ContextMenu closing behavior using WPF's ContextMenu?

I faced similar issue. You can try if you want

notifyIcon1.ContextMenuStrip = new Forms.ContextMenuStrip();
notifyIcon1.ContextMenuStrip.Items.Add("YourMenuItem",null, MenuItemEvent);

I hope this will solve the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM