RadBusyIndi​​cator未显示ViewModel中的PRISM / MEF / WPF

时间:2013-02-13 16:50:04

标签: wpf mvvm prism backgroundworker busyindicator

我在我的WPF应用程序中使用MVVM / PRISM / MEF。它有一个具有多个记录的DataGrid,当双击一行时,单独的视图被添加到具有多个控件的区域,新屏幕的控件初始化大约需要10秒,这就是为什么我想在此期间显示RadBusyIndi​​cator时间。

关注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)
                    {
                    }                   
        }

事件被正确触发并且视图显示正确,但我的问题是Busy指示器根本没有显示,当我双击DataGrid行时,GUI变得无响应,并且在一段时间后出现新视图。我怀疑这是GUI线程繁忙的问题,但是我可以做些什么来避免这种情况,我已经使用过BackgroudWorker了?

修改

1-我正在为IsBusy Property举办PropertyChanged活动。我已经在事件订阅中尝试了Thread的所有选项。即Thread.BackgroundThreadThread.UIThreadThread.PublisherThread。但没有变化。

2-我在Thread.Sleep中测试DisplayView而不是bw_DoWork,并且正确显示RadBusyIndicator,这意味着GUI控件正在GUI线程中初始化,无论我为它创建了BackgroundWorker

2 个答案:

答案 0 :(得分:1)

如果您使用Thread.Sleep(5000)代替this.DisplayView(global_navItem)

,指标会出现吗?

我假设显示视图将使用UI线程,无论您是否使用BackgroundWorker,都会阻止UI。

修改

由于您的UI加载操作似乎阻止了UI线程以及您的BusyIndi​​cator,您可以尝试在不同的线程中托管其中一个。 this article中解释了一种方法。

答案 1 :(得分:0)

最后我找到了解决方案。以下帖子可供参考。我已经使用本文中讨论的方法使用RadBusyIndi​​cator实现了一个子无铬窗口。

Creating multiple UI Threads in WPF