スタック・オーバーフロー Asked by naze84 on November 20, 2021
WPFで2画面構成のアプリを製作していました。これをPrismを用いたMVVMパターンに書き換えようとしています。
単純化した例:
MainWindow,SubWindow
クラスがあります。MainWindow
にあるボタンをクリックすると、Button_Click
が呼ばれて、SubWindow
が表示されます。MainWindow.xaml.cs
は次のようになっています:public partial class MainWindow : Window
{
SubWindow sub;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (sub == null)
{
sub = new SubWindow();
sub.Closed += (s, _e) => sub = null;
sub.Show();
}
sub.Activate();
}
}
これと等価な処理をPrismで書くにはどうすればよいのでしょうか。ViewやViewModelにおいてSubWindow
のインスタンスを生成したり、これをShow,Activate
したりするのはMVVM的ではないと思うので、どうやって実現するのかわからなくなってしまいました。
必要なのは、例示したコードにあるとおり
SubWindow
が表示される。すでに表示されているときは、新たにインスタンスをつくるのではなく、アクティブにするだけShowDialog
ではない(MainWindow
も操作できる)といった動作です。
関連するかもしれない話として、IDialogService
のサンプル(https://prismlibrary.com/docs/wpf/dialog-service.html)を確認してみたものの、そのままだとSubWindow
にあたる画面が複数表示されてしまう上にアクティブにするというメソッドが見当たらず、上記のような動作を実現する方法はわかりませんでした。
以上、よろしくお願いいたします。
たとえば、
デリゲートを用いて、MainWindowを呼び出す「外側」のクラスから機能を入れ込む方法があります。
画面を閉じる処理も記載しています;
MainWindowViewModel:
public Action RequestClose;
public Action RequestToSubWindow;
public Action<string> RequestToSubWindow2;
App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var wnd = new MainWindow();
var mainVM = new MainWindowViewModel();
// When the ViewModel asks to be closed, close the window.
mainVM.RequestClose += delegate {
wnd.Close();
};
mainVM.RequestToSubWindow += displaySubWindow;
mainVM.RequestToSubWindow2 += displaySubWindow2;
wnd.DataContext = mainVM;
wnd.Show();
}
// SubWindow の ViewModel に引数を持たせない場合
private static Action displaySubWindow = () => {
var subWnd = new SubWindow();
var subVM = new SubViewModel();
// When the ViewModel asks to be closed, close the window.
subVM.RequestClose += delegate
{
subWnd.Close();
};
subWnd.DataContext = subVM;
subWnd.ShowDialog();
};
// SubWindow の ViewModel に引数を持たせる場合
private static Action<string> displaySubWindow2 = (name_) => {
var subWnd2 = new SubWindow2();
var subVM2 = new Sub2ViewModel(name_);
// When the ViewModel asks to be closed, close the window.
subVM2.RequestClose += delegate
{
subWnd2.Close();
};
subWnd2.DataContext = subVM2;
subWnd2.Show();
};
質問の「MVVM的ではない」には頷けますが、Microsoftドキュメントに記載されています。
こちらの回答は露骨なコードで綺麗とは言えないので、他の方法があれば私も使ってみたいと思います。
Answered by rairu7 on November 20, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP