バックグラウンドで操作を実行するためにUIスレッドと別のスレッドを使用し、それらの操作の結果でUIを更新するアプリがあります。
これはすべてうまくいきます。ただし、1 つの操作中に、ユーザーに何らかの値を入力するように求める必要があります。順序:
- 実行中の UI スレッド
- コマンド -> バックグラウンドで動作する 2 番目のスレッドが開始されました (作業スレッドと呼びましょう)
- 作業スレッドは、操作を順番に実行しながらステータス情報を UI に送信します
- ある特定の操作中に、作業スレッドが停止します
- ユーザーがオプションを選択するには、ビューを表示する必要があるというメッセージが送信されます
- UI スレッドはこのタイプのメッセージを購読しているため、ビューを表示します
- ユーザーが選択を完了し、ビューを閉じる
- 作業スレッドがユーザーの選択を受け取り、実行を続行します
- 作業スレッドの終了
新しいスレッドを開始するコード:
Thread thread = new Thread(Convert);
thread.SetApartmentState(ApartmentState.STA); // avoid "The calling thread must be STA" exception
thread.Start();
作業スレッドから UI スレッドにステータス情報を送信するコード:
Application.Current.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
(Action<OperationStatus>)delegate(OperationStatus operation)
{
OperationList.Add(operation);
}, status);
ユーザーに確認を求めるコード:
MainViewModel では、作業スレッドの実行中に:
// create ViewModel, that will be used as DataContext for dialog view
var vm = new SelectOptionViewModel(OptionList);
// subscribe to Close event, to get user selection
vm.Close += (s, e) =>
{
_option = vm.SelectedOption;
};
AppMessages.DialogScreen.Send(vm);
MainView では、作業スレッドの実行中に:
AppMessages.DialogScreen.Register(this, vm =>
{
SelectOptionView view = new SelectOptionView();
view.DataContext = vm;
// view.Owner = this; // raises exeption about cross-threading
view.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
view.ShowDialog();
});
問題は、ダイアログ ビューを親ビュー (MainView) の中央に表示するように設定する方法です。「this」は UI スレッドで作成されるため、view.Owner を「this」に設定することはできません。
定義されたシーケンスの順序を維持しながら、アプリでダイアログ ビューを中央に配置するには、ここで何を変更する必要がありますか?