简体   繁体   English

如何将 WPF ContextMenu 与 NotifyIcon 一起使用

[英]How to use a WPF ContextMenu with NotifyIcon

I want to open a WPF ContextMenu when the user clicks the system tray icon.当用户单击系统托盘图标时,我想打开一个 WPF ContextMenu。 With Windows Forms this is straight-forward, just call notifyIcon.ContextMenu = contextMenu and you're set.对于 Windows 窗体,这很简单,只需调用notifyIcon.ContextMenu = contextMenu

On WPF we can not set the ContextMenu that easily because WPF's ContextMenu class is not related to Forms ContextMenu.在 WPF 上,我们不能轻易设置 ContextMenu,因为 WPF 的 ContextMenu 类与 Forms ContextMenu 无关。 The alternative I have been pursuing is to handle NotifyIcon's Click event to open the WPF-style ContextMenu.我一直在追求的替代方法是处理 NotifyIcon 的 Click 事件以打开 WPF 样式的 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).这种方法的问题是 WPF ContextMenu 永远不会得到任何提示用户已经离开菜单并应该关闭(例如,当用户在菜单边界之外单击时)。 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.没有触发任何 Focus 或 MouseCapture 事件,除了单击其中一项之外,我无法关闭菜单。

So the question here, to put slightly different, is: how do I properly emulate the NotifyIcon's ContextMenu closing behavior using WPF's ContextMenu?所以这里的问题,稍微不同的是:如何使用 WPF 的 ContextMenu 正确模拟 NotifyIcon 的 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.我希望这能解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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