none
MVVM利用時にShowDatailで、CenterOwnerを有効にしたい。 RRS feed

  • 質問

  • いつも御世話になっております。
    MVVMを利用して、コーディングを行っております。

    特定のイベント内で、ShowDaialog()を行う箇所があり、
    その対象のWindowsに対して、CenterOwnerを指定しているのですが、
    親画面に対して、中央に画面が表示されませんでした。

    検討違いかもしれませんが、開かれるWindowsが、親となるWindowsが分ってないのが原因ではないかと、
    思ったのですが、新しいWindowsに対して、どうやってその情報を与えたらよいか?が、分っておりません。

    RelayCommand testCommand;
    public ICommand TestCommand
    {
        get
        {
            if (testCommand == null)
            {
                testCommand = new RelayCommand(
                    param =>
                    {
                        var window = new TestEdit(); // Window
                        var viewModel = new TestEditViewModel(); // ViewModel
                        viewModel.RequestClose += delegate
                        {
                            window.DialogResult = true;
                            window.Close();
                        };
                        window.DataContext = viewModel;
                        window.ShowDialog();
                    }
                );
            }
            return testCommand;
        }
    }

    CenterOwnerを有効(親画面に対して中央にくるよう)にするために、
    アドバイスをいただけないでしょうか?

    お手数をおかけしますが、宜しくお願い致します。
    2009年10月9日 9:31

回答

  • RelayCommand をつかっているなら Viewがわで <Button Command="{Binding Path=TestCommand}" CommandParameter="{Binding ElementName=OwnerWindow}" /> でパラメータとしてWindowをわたせます。これはtrapemiyaさんの解説と同じです。

    但しこの場合は単なるオーナーウィンドウのオブジェクトとしての意味だけで渡しているのでいいのですが、VMがViewの構造を知らないと使えないようなVMがViewに依存する使い方はやめたほうがいいです。

    あとは、Window.Owner プロパティ で  var window = new TestEdit(); の window の Owner を指定してやればOKです。
    http://msdn.microsoft.com/ja-jp/library/system.windows.window.owner.aspx
    このばあいは window.Owner = param ですね。

    えムナウ@わんくま同盟 Microsoft MVP Visual Studio C# Since 2005/01-2009/12
    • 回答としてマーク a_山田 2009年10月19日 8:51
    2009年10月11日 17:51
  • この場合はWindowへのキャストは必要ないですし、オーナーオブジェクト(UserControlも含む)という意味でしないほうがいいんじゃないでしょうか?

    特定の型にキャストするのは確かにまずいと思いますが、場合によってはWindowもしくはUserControlにキャストすることは私の中では今のところ許容範囲内です。SilverlightのMVVMを見ていると、WPFほどインスタンスの依存性がきれいに分離できていないので、どうしたものかなぁと私も悩みどころなんです。

    (参考)
    Silverlight 2 アプリケーションでの Model-View-ViewModel
    http://msdn.microsoft.com/ja-jp/magazine/dd458800.aspx
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク a_山田 2009年10月19日 8:51
    2009年10月13日 8:01
    モデレータ

すべての返信

  • 親となるWindowのインスタンスをコマンドのパラメータで渡せます。私の記事が参考になりませんでしょうか?

    【WPF】ViewからViewModelへViewのインスタンスを渡す(CommandParameter経由編)
    http://blogs.wankuma.com/trapemiya/archive/2009/08/10/180023.aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年10月10日 7:39
    モデレータ
  • RelayCommand をつかっているなら Viewがわで <Button Command="{Binding Path=TestCommand}" CommandParameter="{Binding ElementName=OwnerWindow}" /> でパラメータとしてWindowをわたせます。これはtrapemiyaさんの解説と同じです。

    但しこの場合は単なるオーナーウィンドウのオブジェクトとしての意味だけで渡しているのでいいのですが、VMがViewの構造を知らないと使えないようなVMがViewに依存する使い方はやめたほうがいいです。

    あとは、Window.Owner プロパティ で  var window = new TestEdit(); の window の Owner を指定してやればOKです。
    http://msdn.microsoft.com/ja-jp/library/system.windows.window.owner.aspx
    このばあいは window.Owner = param ですね。

    えムナウ@わんくま同盟 Microsoft MVP Visual Studio C# Since 2005/01-2009/12
    • 回答としてマーク a_山田 2009年10月19日 8:51
    2009年10月11日 17:51
  • ご回答ありがとうございました。

    trapemiyaさんの教えていただいたアドレスですが、
    エラーが発生して、閲覧できませんでしたのでキャッシュより閲覧させて頂きました。

    http://blogs.wankuma.com/trapemiya/archive/2009/08/10/180023.aspx


    理解が間違っておりましたら、申し訳ございません。
    Window.Owner プロパティ で  var window = new TestEdit(); の window の Owner を利用する場合に関して
    教えていただきました件ですが、ViewModelの中から、window.Owner = param を利用する場合、
    ViewModelで親となるWindowの情報がわからないと、window.Owner 渡せないと思うのですが、
    親となるWindowsの情報はどのように取得すればよろしいでしょうか?

    お手数をおかけしますが、宜しくお願い致します。

    2009年10月13日 2:10
  • trapemiyaさんの教えていただいたアドレスですが、
    エラーが発生して、閲覧できませんでしたのでキャッシュより閲覧させて頂きました。
    がまん強く再試行しているとそのうち開きます。(^^;


    Window.Owner プロパティ で  var window = new TestEdit(); の window の Owner を利用する場合に関して
    教えていただきました件ですが、ViewModelの中から、window.Owner = param を利用する場合、
    ViewModelで親となるWindowの情報がわからないと、window.Owner 渡せないと思うのですが、
    親となるWindowsの情報はどのように取得すればよろしいでしょうか?
    私のブログに書いた通り、親windowにそのXAMLでName="MyWindow"と名前を付けておき、
    Command="{Binding Path=testCommand}" CommandParameter="{Binding ElementName=MyWindow}"
    とすればparamに親windowのインスタンスが渡ってきます。object型なので必要に応じてWindow型へのキャストを行います。
    RelayCommandはAction<T>デリゲートをパラメータにとりますので、そのデリゲートで一つのパラメータを受け取れます。ここではそのパラメータに親windowのインスタンスを渡しています。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年10月13日 2:53
    モデレータ
  • 私のブログに書いた通り、親windowにそのXAMLでName="MyWindow"と名前を付けておき、
    Command="{Binding Path=testCommand}" CommandParameter="{Binding ElementName=MyWindow}"
    とすればparamに親windowのインスタンスが渡ってきます。object型なので必要に応じてWindow型へのキャストを行います。
    RelayCommandはAction<T>デリゲートをパラメータにとりますので、そのデリゲートで一つのパラメータを受け取れます。ここではそのパラメータに親windowのインスタンスを渡しています。
    この場合はWindowへのキャストは必要ないですし、オーナーオブジェクト(UserControlも含む)という意味でしないほうがいいんじゃないでしょうか?
    えムナウ@わんくま同盟 Microsoft MVP Visual Studio C# Since 2005/01-2009/12
    2009年10月13日 5:02
  • この場合はWindowへのキャストは必要ないですし、オーナーオブジェクト(UserControlも含む)という意味でしないほうがいいんじゃないでしょうか?

    特定の型にキャストするのは確かにまずいと思いますが、場合によってはWindowもしくはUserControlにキャストすることは私の中では今のところ許容範囲内です。SilverlightのMVVMを見ていると、WPFほどインスタンスの依存性がきれいに分離できていないので、どうしたものかなぁと私も悩みどころなんです。

    (参考)
    Silverlight 2 アプリケーションでの Model-View-ViewModel
    http://msdn.microsoft.com/ja-jp/magazine/dd458800.aspx
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク a_山田 2009年10月19日 8:51
    2009年10月13日 8:01
    モデレータ
  • えムナウ様、trapemiya様、ご回答ありがとうございました。

    MVVMを利用した場合、利用の用途によっては完全分離は難しいんですね。

    ご回答ありがとうございました。
    2009年10月19日 8:51