2

WPF アプリケーションに MVVM/PRISM/MEF を使用しています。複数のレコードを持つ 1 つの DataGrid があり、1 つの行をダブルクリックすると、複数のコントロールを含むリージョンに別のビューが追加されます。コントロールの初期化には新しい画面で約 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.BackgroundThreadThread.UIThreadおよびThread.PublisherThread。しかし変化なし。

2-Thread.Sleepではなく、適切に表示されていることをテストしDisplayViewました。これは、GUI コントロールを作成したにもかかわらず、GUI スレッドで GUI コントロールが初期化されていることを意味します。bw_DoWorkRadBusyIndicatorBackgroundWorker

4

2 に答える 2

1

Thread.Sleep(5000)の代わりに使用した場合、インジケーターは表示されますthis.DisplayView(global_navItem)か?

ビューを表示するとUIスレッドが使用され、使用するBackgroundWorkerかどうかに関係なくUIがブロックされると思います。

編集:

UIの読み込み操作でUIスレッドがブロックされ、BusyIndi​​catorがブロックされているように見えるため、それらの1つを別のスレッドでホストしてみることができます。この記事では、アプローチについて説明します。

于 2013-02-13T22:19:26.113 に答える
0

最後に、解決策を見つけました。参考までに以下の投稿をご覧ください。この投稿で説明したアプローチを使用して、RadBusyIndi​​cator を使用して子クロムレス ウィンドウを実装しました。

WPF で複数の UI スレッドを作成する

于 2013-02-19T07:34:18.820 に答える