Displaying WPF-“NotifyIcon” on a separate thread

萝らか妹 提交于 2020-01-04 02:03:08

问题


I am currently working on an office add-in and I need to show a notification dialog that displays progress, I'm using Philipp Sumi's wpf-notifyicon.

I need to display the notifyicon from a separate thread as I have a lot of code that already executes on the main thread, this causes the wpf-notifyicon to block and wait because the messages in the windows message queue are not being processed.

I know that I should rather execute this time consuming code on a separate thread, and display the notifyicon from the main thread and update it accordingly, but that is unfortunately not an alternative because this whole solution is single-threaded.

Example:

    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 I have been able to progress a little further with this updated code:

I'm creating the TaskbarIcon object on a new thread , and using Application.Run to process the application message loop on that thread...

    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:


I have solved my problem, I had to initialize the notifyIcon on a separate STA thread and use Application.Run in order to start pumping windows messages on that thread.

        var myThread = new Thread(delegate()
        {
            notifyIcon = new NotifyIcon();

            Application.Run();
        });

        myThread.SetApartmentState(ApartmentState.STA);
        myThread.Start();

Then I just had to Invoke the UI of my notification dialog.



来源:https://stackoverflow.com/questions/10718369/displaying-wpf-notifyicon-on-a-separate-thread

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!