简体   繁体   English

当应用程序运行后台工作程序时,NotifyIcon 不显示上下文菜单

[英]NotifyIcon not showing context menu when app running background worker

My WPF application shows a window and when the user clicks a button, it begins to run its tasks and minimizes to a tray item in the notification area with a context menu where I would like the user to be able to cancel the operation.我的 WPF 应用程序显示一个窗口,当用户单击按钮时,它开始运行其任务并最小化到通知区域中的托盘项目,并带有上下文菜单,我希望用户能够在其中取消操作。

The context menu worked before using a BackgroundWorker, however, cancellation did not.上下文菜单在使用 BackgroundWorker 之前工作,但是,取消没有。 Since I've implemented a background worker,the context menu does not appear once the .runworkerasync() method has run.因为我已经实现了一个后台工作者,一旦 .runworkerasync() 方法运行,上下文菜单就不会出现。

My Notify Icon:我的通知图标:

public NotifyIcon myNotifyIcon;

When my application runs I set it up like this:当我的应用程序运行时,我将其设置如下:

private void setup_NotifyIcon()
{
    myNotifyIcon = new NotifyIcon();
    setTrayIcon();

    myNotifyIcon.MouseDown += new MouseEventHandler(myNotifyIcon_MouseDown);

    var menuItemCancel = new MenuItem("Cancel Parsing");
    var contextMenu = new ContextMenu();
    menuItemCancel.Click += new System.EventHandler(this.menuItemCancel_Click);

    contextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { menuItemCancel });
    myNotifyIcon.ContextMenu = contextMenu;

}

    private void menuItemCancel_Click(object Sender, EventArgs e)
    {
        //do something
    }

    void myNotifyIcon_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            //do something
        }
    }

Then when the user clicks the button:然后当用户点击按钮时:

worker.RunWorkerAsync();

Why won't myNotifyIcon.MouseDown += new MouseEventHandler(myNotifyIcon_MouseDown);为什么 myNotifyIcon.MouseDown += new MouseEventHandler(myNotifyIcon_MouseDown); trigger the context menu?触发上下文菜单?

The solution turned out to be a threading issue as suggested by Sebastian in the comments.正如 Sebastian 在评论中所建议的那样,该解决方案被证明是一个线程问题。

The key was to start the icon on another thread using Application.Run() and to make the icon visible within that code.关键是使用 Application.Run() 在另一个线程上启动图标并使图标在该代码中可见。

Once this was done, right-clicking on the icon worked, as did the cancellation functionality being handled.完成此操作后,右键单击该图标即可,正在处理的取消功能也是如此。

    private void setup_NotifyIcon()
    {
        Thread notifyThread = new Thread(
        delegate ()
        {
            myNotifyIcon = new NotifyIcon();
            setTrayIcon();

            myNotifyIcon.MouseDown += new MouseEventHandler(myNotifyIcon_MouseDown);

            mnuCancel = new MenuItem("Cancel Parsing");
            menu = new ContextMenu();
            mnuCancel.Click += new System.EventHandler(menuItemCancel_Click);

            menu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { mnuCancel });
            myNotifyIcon.ContextMenu = menu;

            myNotifyIcon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info; //Shows the info icon so the user doesn't thing there is an error.
            myNotifyIcon.BalloonTipText = "The P6 Parser will minimize to the system tray while working.";
            myNotifyIcon.BalloonTipTitle = "Processing...";

            myNotifyIcon.Visible = true;
            myNotifyIcon.ShowBalloonTip(500);

            myNotifyIcon.Visible = true;
            System.Windows.Forms.Application.Run();
        });
        notifyThread.Start();

    }

Program.cs中将 Annotation [STAThread]更改为[MTAThread]

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

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