MVVM デザイン パターンに従う WPF アプリケーションを開発しています。スレッド化には、Backgroundworker を使用する予定です。ビューモデルから、スレッドを開始して時間のかかる操作を実行する必要があります。スレッドが実行されるまで待機ダイアログを表示する方法を教えてください。可能であれば、サンプルコードを提供してください。よろしく、 アニルバン
3 に答える
バックグラウンド ワーカー (または他の非同期アクション) がビジーであることを示すプロパティを ViewModel に追加できます。
View は、このプロパティに bind をバインドして、進行状況バーまたはその他のビジー インジケーターを表示できます。
プロパティを正しく設定およびリセットしてください。
編集
WPF でモーダル ダイアログを作成するには、この質問/回答を参照してください: WPF でモーダル ダイアログを作成するにはどうすればよいですか?
別の方法として、次のセットアップ (疑似コード) を使用できます。
<Window>
<Grid>
<Grid x:Name="regularContent">
</Grid>
<Grid x:Name="Overlay" Visibility="Collapsed">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Progressbar Value="{Binding Path=Progress}" />
</StackPanel>
</Grid>
</Grid>
</Window>
コードビハインド:
private void ShowPopup()
{
RegularContent.IsEnabled = false;
Overlay.Visibility = Visibility.Visible;
}
private void ClosePopup()
{
RegularContent.IsEnabled = true;
Overlay.Visibility = Visibility.Collapsed;
}
ユーザーが通常のコンテンツにタブ移動できないようにするには、必ず通常のコンテンツを無効にしてください。
私が行ったようにビューを完全にブロックするのではなく、同じ構造を使用してビューの一部をブロックアウトすることができます。
ProgressBar がバインドされている ViewModel の Progress プロパティは、UI スレッドで変更する必要があります。ReportProgress イベントが UI スレッドで発生するため、自動的に実行される backgroundworker を使用している場合。
別の方法でワーカー スレッドを作成する場合は、必ずディスパッチャを使用して Progress プロパティを更新してください。
Windows Phone で使用しました:
private readonly BackgroundWorker worker = new BackgroundWorker();
private PerformanceProgressBar loader = new PerformanceProgressBar();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
bar.IsIndeterminate = true;
Bar.Enabled = true;
}
private void worker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
bar.Enabled = false;
}
worker.RunWorkerAsync();
MVVM 構造を定義する場合: PerformanceProgressBar "Invalid cross-thread access" 例外
もちろん、同様のユーザー コントロールが WPF にも存在します: http://wpftoolkit.codeplex.com/wikipage?title=Extended%20WPF%20Toolkit%20Controls
最も簡単な方法は、wpf busyindicator ( http://elegantcode.com/2011/10/07/extended-wpf-toolkitusing-the-busyindicator/ ) を使用することです。
モデル モデルのいくつかの thread_is_busy_flag_property にバインドできます (ロケーター パターンを介してアプリケーション全体のリソースを介してアクセスできるシングルトーンで使用することをお勧めします。xaml およびモデル ビュー/コード ビハインドで簡単に共有できます)。
このフラグを設定するときは、スレッド セーフを忘れないでください (または、AutoResetEvent/ManualResetEventを使用してバックグラウンド操作の終了をキャッチできます)。また、BackgroundWorker/QueueUserWorkItem の代わりに TPL とタスク (より堅牢な方法) を使用することをお勧めします。