2013-02-13 84 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