RadBusyIndicator не показывает PRISM/MEF/WPF из ViewModel

Я использую MVVM/PRISM/MEF для своего приложения WPF. Он имеет одну DataGrid с несколькими записями, и когда дважды щелкается одна строка, в область с несколькими элементами управления добавляется отдельное представление, инициализация элементов управления занимает около 10 секунд для нового экрана, поэтому я хочу показать RadBusyIndicator во время этого время.

Следуя в 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, но что я могу сделать, чтобы избежать этого, я использовал BackgroudWorker уже?

РЕДАКТИРОВАТЬ

1- Я поднимаю событие PropertyChanged для свойства IsBusy. и я уже перепробовал все опции для темы в подписке на событие. т.е. Thread.BackgroundThread, Thread.UIThread а также Thread.PublisherThread, но без изменений.

2- Я проверил Thread.Sleep скорее что DisplayView в bw_DoWorkи его показ RadBusyIndicator правильно, это означает, что элементы управления GUI инициализируются в потоке GUI, независимо от того, я создал BackgroundWorker для этого.

2 ответа

Решение

Наконец-то я нашел решение. Для справки можно посмотреть следующий пост. Я реализовал дочернее окно без хрома с RadBusyIndicator, используя подход, описанный в этом посте.

Создание нескольких потоков пользовательского интерфейса в WPF

Появится ли индикатор, если вы используете Thread.Sleep(5000) вместо this.DisplayView(global_navItem)?

Я предполагаю, что показ представления будет использовать поток пользовательского интерфейса, и это заблокирует пользовательский интерфейс, независимо от того, используете ли вы BackgroundWorker или нет.

Редактировать:

Похоже, что ваша операция загрузки пользовательского интерфейса блокирует поток пользовательского интерфейса, а также ваш BusyIndicator, вы можете попробовать разместить один из них в другом потоке. Подход объясняется в этой статье.

Другие вопросы по тегам