首页 文章

在单独的线程上显示WPF-“NotifyIcon”

提问于
浏览
2

我目前正在处理办公室加载项,我需要显示一个显示进度的通知对话框,我正在使用Philipp Sumi's wpf-notifyicon .

我需要从一个单独的线程显示notifyicon,因为我有很多代码已经在主线程上执行,这导致wpf-notifyicon阻塞并等待,因为Windows消息队列中的消息没有被处理 .

我知道我应该在一个单独的线程上执行这个耗时的代码,并从主线程显示notifyicon并相应地更新它,但遗憾的是这不是一个替代方案,因为整个解决方案是单线程的 .

例:

private FancyPopup fancyPopup;

    private void button1_Click(object sender, EventArgs e)
    {
        notifyIcon = new TaskbarIcon();
        notifyIcon.Icon = Resources.Led;

        fancyPopup = new FancyPopup();

        Thread showThread = new Thread(delegate()
        {
            notifyIcon.ShowCustomBalloon(fancyPopup, System.Windows.Controls.Primitives.PopupAnimation.Fade, null);
        });

        showThread.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        fancyPopup.TextB.Text = "Doing something...";

        //Keep the main thread busy.
        Thread.Sleep(5000);

        fancyPopup.TextB.Text = "Done doing something...";
    }

Update 我已经用这个更新的代码进一步发展了:

我正在新线程上创建TaskbarIcon对象,并使用Application.Run处理该线程上的应用程序消息循环...

private FancyPopup fancyPopup;

    private void button1_Click(object sender, EventArgs e)
    {
        Thread showThread = new Thread(delegate()
        {
            notifyIcon = new TaskbarIcon();
            notifyIcon.Icon = Resources.Led;

            fancyPopup = new FancyPopup();


            notifyIcon.ShowCustomBalloon(fancyPopup, System.Windows.Controls.Primitives.PopupAnimation.Fade, null);

            System.Windows.Forms.Application.Run();
        });

        showThread.SetApartmentState(ApartmentState.STA);
        showThread.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        fancyPopup.Dispatcher.Invoke(new Action(delegate
        {
            fancyPopup.TextB.Text = "Doing something...";
        }));

        //Keep the main thread busy.
        Thread.Sleep(5000);

        fancyPopup.Dispatcher.Invoke(new Action(delegate
        {
            fancyPopup.TextB.Text = "Done doing something..."; 
        }));
    }

1 回答

  • 2

    我已经解决了我的问题,我不得不在一个单独的STA线程上初始化 notifyIcon 并使用 Application.Run 来开始在该线程上抽取窗口消息 .

    var myThread = new Thread(delegate()
            {
                notifyIcon = new NotifyIcon();
    
                Application.Run();
            });
    
            myThread.SetApartmentState(ApartmentState.STA);
            myThread.Start();
    

    然后我只需要调用我的通知对话框的UI .

相关问题