2013-02-13 66 views
2

我正在爲我的WPF應用程序使用MVVM/PRISM/MEF。它有一個包含多條記錄的DataGrid,當雙擊一行時,一個單獨的視圖被添加到帶有多個控件的區域,初始化控件對於新屏幕大約需要10秒,這就是爲什麼我想在該過程中顯示RadBusyIndi​​cator時間。RadBusyIndi​​cator沒有顯示來自ViewModel的PRISM/MEF/WPF

在XAML

<!-- This is Main View --> 
<!-- Module: MainModule, ViewModel: MainViewViewModel --> 
<telerik:RadBusyIndicator IsBusy="{Binding IsBusy}" BusyContent="{Binding BusyContent}"> 
<!-- All PRISM regions are here --> 
</telerik:RadBusyIndicator> 

視圖模型以下是

class MainViewViewModel : ViewModelBase 
    { 
     ImportingConstructor] 
     public MainViewViewModel(IEventAggregator eventAggregator, IRegionManager regionManager, IServiceLocator serviceLocator) 
      :base(eventAggregator, regionManager, serviceLocator) 
     { 
      eventAggregator.GetEvent<BusyStateChangedEvent>().Subscribe(OnBusyStateChanged,ThreadOption.BackgroundThread); 
     } 

     #region BusyStateChanged 

     private void OnBusyStateChanged(bool newState) 
     { 
      IsBusy = newState; 
     } 

     #endregion 
} 

而且在當DataGrid行被雙擊ViewModelBase函數被調用,如下

public class ViewModelBase 
{ 
     private NavigationItem global_navItem = null; 

     public virtual void OnNavigationItemChanged(NavigationItem item) 
     { 
      changeNav = true; 
      global_navItem = item; 

      //Firing event to change the state 
      EventAggregator.GetEvent<BusyStateChangedEvent>().Publish(true); 

      //Using BackgroundWorker, but its not showing any Busy Indicator as well 
      var bw = new BackgroundWorker(); 
      bw.DoWork += bw_DoWork; 
      bw.RunWorkerCompleted += bw_RunWorkerCompleted; 

      bw.RunWorkerAsync(); 
     } 

     void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      //Setting busy indicator to false 
      EventAggregator.GetEvent<BusyStateChangedEvent>().Publish(false); 
     } 

     void bw_DoWork(object sender, DoWorkEventArgs e) 
     { 
      //DisplayView function is taking too long 
      if (global_navItem != null) this.DisplayView(global_navItem); 
     } 
} 

public void DisplayView(NavigationItem item) 
     { 
        try 
        { 
         //This call is taking long as it initializes the View 
         MyCustomeUserControl view = this.ServiceLocator.GetInstance<MyCustomeUserControl>(item.viewName); 

         view.Region = this.Region; 
        }catch(Exception e) 
        { 
        }     
     } 

其他視圖事件正在被正確觸發並且視圖顯示正確,但是我的問題是繁忙指示器根本沒有顯示,當我雙擊DataGrid行時,GUI變得沒有響應,一段時間後出現新的視圖。我懷疑這是GUI線程繁忙的問題,但我能做些什麼來避免這種情況,我已經使用BackgroudWorker了?

編輯

1 - 我養的PropertyChanged事件IsBusy屬性。並且我已經嘗試了Thread in event訂閱中的所有選項。即Thread.BackgroundThreadThread.UIThreadThread.PublisherThread。但沒有變化。

2-我已經測試Thread.Sleep寧可DisplayViewbw_DoWork,其示出正常RadBusyIndicator,所以這意味着GUI控件在GUI線程被初始化,不管我已經創建了它BackgroundWorker

+0

您發佈的代碼似乎沒問題。只是一個愚蠢的問題(我的意思是沒有傷害)您是否爲IsBusy屬性提出PropertyChanged事件?我只需要問...還有一件事... [這裏](http://msdn.microsoft.com/en-us/library/ff921122(v = pandp.20).aspx)它說* If你需要能夠在接收到事件時更新用戶界面元素,訂閱在用戶界面線程上接收事件。*如果我是你,我會在ThreadOption.UIThread訂閱BusyStateChangedEvent時切換ThreadOption.BackgroundThread。但這些只是想法... – 2013-02-13 22:18:14

+0

謝謝@ViktorLaCroix,是的我正在提高'IsBusy'屬性的PropertyChanged事件。並且我已經嘗試了Thread in event訂閱中的所有選項。即'Thread.BackgroundThread','Thread.UIThread'和'Thread.PublisherThread'。但沒有變化。 – 2013-02-14 06:16:14

+0

現在它變得有趣:)所以,請你用這些額外的信息編輯你的問題?並且請不要忘記,當您切換DoWork方法的主體時,一切正常。Thread.Sleep – 2013-02-14 08:31:50

回答

0

最後我找到了解決方案。以下的帖子可供參考可以看出。我已經用RadBusyIndi​​cator實現了一個使用本文討論的方法的兒童無窗口窗口。

Creating multiple UI Threads in WPF

1

如果您使用Thread.Sleep(5000)而不是this.DisplayView(global_navItem),指示器是否會顯示?

我假設顯示視圖將使用UI線程,這將阻止用戶界面,無論您是否使用BackgroundWorker或不。

編輯:

因爲它看起來像你的用戶界面加載操作阻塞UI線程,所以你的BusyIndi​​cator控件,你可以嘗試舉辦他們中的一個在不同的線程。在this article中解釋了一種方法。

+0

感謝您的建議,是的,我嘗試使用Thread.Sleep並正確顯示BusyIndi​​cator。 :(。什麼可以是任何其他的方法來顯示一個繁忙的指標,而一個沉重的圖形用戶界面正在加載? – 2013-02-14 06:45:45

+0

這並不容易,有方法顯示一個BusyIndi​​cator在不同的線程,但UI線程。很快就有了答案。 – MatthiasG 2013-02-14 10:11:09