2012-05-23 59 views
2

我目前正在使用辦公室外接程序,並且需要顯示顯示進度的通知對話框,我正在使用Philipp Sumi's wpf-notifyicon在單獨的線程上顯示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..."; 
    } 

更新 我已經能夠進步了一點點進一步與此更新的代碼:

我創建一個新的線程TaskbarIcon對象,並使用應用程序.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..."; 
     })); 
    } 
+0

應該從UI線程調用所有視覺元素。您應該將線程中繁重的進程分開,以便UI線程不會被阻塞。 –

+0

我已經更新了OP,檢查出來。 – animaonline

回答

2

我已經解決了米y問題,我必須在單獨的STA線程上初始化notifyIcon並使用Application.Run以便在該線程上開始泵送Windows消息。

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

      Application.Run(); 
     }); 

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

然後,我只需要調用我的通知對話框的用戶界面。