2

我正在为我的 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)
                    {
                    }                   
        }

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

编辑

1- 我正在为 IsBusy 属性引发 PropertyChanged 事件。我已经在事件订阅中尝试了 Thread 的所有选项。即和。Thread.BackgroundThread_ 但没有变化。Thread.UIThreadThread.PublisherThread

2-我已经在 中进行Thread.Sleep了测试,并且它的显示正确,所以这意味着 GUI 控件正在 GUI 线程中初始化,无论我是否为它创建了一个。DisplayViewbw_DoWorkRadBusyIndicatorBackgroundWorker

4

2 回答 2

1

如果您使用Thread.Sleep(5000)而不是,指示符会出现this.DisplayView(global_navItem)吗?

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

编辑:

由于您的 UI 加载操作似乎阻塞了 UI 线程,因此您的 BusyIndi​​cator,您可以尝试将其中一个托管在不同的线程中。本文解释了一种方法。

于 2013-02-13T22:19:26.113 回答
0

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

在 WPF 中创建多个 UI 线程

于 2013-02-19T07:34:18.820 回答