web-dev-qa-db-ja.com

PrismとMVVMパターンを使用してWPFでモーダルダイアログを作成する「きれいな」方法

昨日、Googleを使用して、PRISM 4.1とMVVMパターンを備えたWPFで素晴らしい再利用可能なモーダルダイアログを作成する方法をいくつか見つけました。いくつかの例を見つけましたが、私はそれらが好きだったほど「きれい」ではなかったと言わなければなりません。

これ: WPFモーダルダイアログ (mvvmなし->使用しない)

これはかなりいいです: MVVMパターンを使用しているときにダイアログを表示する (ただし、IUnityコンテナーを使用しているので不要な自作のServiceLocatorを使用しています。ロジックを使用して次のように書き直すことができます。ユニティですが、正直なところ、これは「きれい」な方法ではありません。

まあしばらくしてからWebで情報を検索すると、あるブログ(現時点ではソースを見つけることができません)から、PRISMフレームワークに「相互作用要求」と呼ばれるものがあることがわかりました。それで、私はプリズムのドキュメントをチェックアウトし、「高度なmvvmシナリオ」というトピックの下に小さな部分を見つけましたが、ドキュメントに記載された情報は十分ではありません。

誰かがmvvmを使用してプリズムwpfで素晴らしいモーダルダイアログを実現する方法について、良い例やブログ記事があるかどうか知りたいのですが。

[〜#〜] edit [〜#〜]:コメント内の質問について:

モーダルダイアログがすばらしいのはなぜですか?

確かに良い質問です。

  1. モーダルである必要があります(ダイアログが開いている間、UIの残りの部分はフリーズする必要があります)
  2. ダイアログビューは、独自のビューモデルを持つことができます。または、少なくとも、オブジェクトのインスタンスをダイアログビューに与えて、オブジェクトを親ビューに戻したいです。
  3. ビューは独自の「xaml」ファイルである必要があります
  4. .NETのダイアログ結果機能、または少なくともユーザーがダイアログでクリックした応答を取得する方法
17
darkdog

PRISM 5.0は、モーダルダイアログを表示するための簡単なソリューションを考え出しました。 PopupWindowActionの使用。

<prism:InteractionRequestTrigger SourceObject="{Binding CustomPopupViewRequest, Mode=OneWay}">
    <prism:PopupWindowAction>
        <prism:PopupWindowAction.WindowContent>
            <views:CustomPopupView />
        </prism:PopupWindowAction.WindowContent>
    </prism:PopupWindowAction>
</prism:InteractionRequestTrigger>
20
Jawahar

インタラクションリクエストにはもう少し事前の作業が必要ですが、MVVMピュリストの観点から見ると、間違いなく正しい方法です...

これをPrismで行う方法の例をKarl ShifflettのMVVM In The Box トレーニング拡張機能で見ました。

私が覚えているように、この例は端がかなり荒れていましたが、正しい方向に設定する必要があります。

この種のビュー内「ダイアログ」の問題は、ダイアログが親ウィンドウの境界の外に出られないことです。プラス面では、多くの豪華なレイアウトやアニメーションなどを行うことができます。

5
Mark

こちら から私の投稿を確認してください

そのシンプル、そのmvvm、そのサービス、およびビューモデルでの「実行する必要があるすべて」は次のとおりです。

var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);
2
blindmeis

警告:私はPRISMを使用していません。私の回答は、WPFとMVVMの使用のみを想定しています。あなたの要件のリストはPRISMなしでも満たすことができるので(これはとにかく基本的なソリューションの上に追加することができます)、これは大きな問題とは思いません。

Github にプロジェクトがあり、モーダルコンテンツを表示できるModalContentPresenterというカスタムFrameworkElementを提供しています。要素は基本的に2つのペインで構成され、一方が他方の上に重なっています。バックペインはメインコンテンツをホストし、フロントペインはモーダルコンテンツをホストします。要素には、モーダルコンテンツを表示するかどうかを制御する依存関係プロパティがあります。

要素は基本的な「モーダル」機能のみを提供し、(ほとんどのWPFコントロールのように)任意のコンテンツをホストできます。たとえば、表示しているモーダルコンテンツがウィンドウのような外観と動作(タイトル、閉じるボタン、マウスドラッグなど)である場合でも、いくつかの作業を行う必要があります。

ModalContentPresenterが要件に対処する方法は次のとおりです。

モーダルである必要があります(ダイアログが開いている間、UIの残りの部分はフリーズする必要があります)

ModalcontentPresenterは視覚的階層内の任意のレベルに配置でき、モーダルコンテンツの背後にあるもの(表示される場合)はinaccessibleになります。コントロールは引き続き有効になり、バインドされているviewModelの変更に反応しますが、ユーザーはマウスとキーボードを使用してコントロールに移動したり操作したりできなくなります。

ダイアログビューは、独自のビューモデルを持つことができます。または、少なくとも、オブジェクトのインスタンスをダイアログビューに与えて、オブジェクトを親ビューに戻したいです。

このStackoverflowの回答 は、これを達成することをお勧めします。

ビューは独自の「xaml」ファイルである必要があります

プライマリとモーダルの両方のコンテンツは、インラインxamlまたは個別のxamlファイル(UserControlなど)を使用して定義できます。

.NETのダイアログ結果機能、または少なくともユーザーがダイアログでクリックした応答を取得する方法

上記のリンクされた回答は、モーダルコンテンツから「回答」を取得する方法を示しています。基本的な前提は、viewModelが正常に通信することです(直接またはイベントバスなどの他の手段を介して)。唯一の違いは、ユーザーが「モーダル」データのみを操作できる方法でコンテンツを表示していることです。

1
Benjamin Gale