ポップアップに関する VM の責任について質問がありました。アプリがメッセージ ボックスまたは何らかのダイアログ (MVVM を使用) をポップする場合、次の 2 つのオプションがあります。
- 悪いと思われる VM に UI (ShowDialog()) コードを配置する
- UI がサブスクライブできる何らかのイベントを VM に送信させ、コード ビハインドでダイアログを表示します (ただし、コード ビハインドをゼロにするよう努めています :) )
皆さんは、このケースをどのように処理しますか?
ポップアップに関する VM の責任について質問がありました。アプリがメッセージ ボックスまたは何らかのダイアログ (MVVM を使用) をポップする場合、次の 2 つのオプションがあります。
皆さんは、このケースをどのように処理しますか?
UIコードをVMに配置しないでください。これにより、将来的に多くの問題が発生します。
ウィンドウまたはダイアログをポップしたい場合、通常2つのケースがあります。リストをダブルクリックしたときの詳細ビューなどのビジネスケースのためにそれを行っているか、オプションウィンドウをポップするなどの完全なUIベースです。前者の場合はVMでイベントを使用するのが最適であり、後者の場合はイベントハンドラーを使用するだけです。経験則として、アクションを実行するために(重要な)VM変数が必要ない場合は、イベントハンドラーを使用する必要があります。
何よりも、頭を使って判断を信頼してください。どちらを使うかがすぐにわかります。
オニキスをチェックしてください。これは、サービスと Service Locator または Dependency Injection パターンのいずれかの使用に基づく MV-VM ライブラリです (完全な開示: 私は作成者です)。MessageBox と共通ダイアログ用のサービスがあり、独自のサービスを追加するのも非常に簡単です。
他の人が言及していない他のいくつかのオプション:
リレーコマンド
VM は、私が「リレー コマンド」と呼んでいるコマンドを実行します。これは他の誰かが処理するコマンドであり、VM は誰であろうと気にしません。コマンドの実行は、Executed
イベントを発生させるだけです。ビューはこのイベントをサブスクライブし、コンテンツを new に表示しますWindow
(コンテンツはコマンド パラメーターとして渡されます)。
リレー コマンドはルーティング コマンドではないことに注意してください。実行ロジックでハンドラーを検索しません。イベントを発生させるだけです。
サービス
ウィンドウに何かを表示する必要があるインスタンスが多数ある場合は、それを処理する UI サービスを記述します。VM は、このサービス (簡単にモックできる) に依存して、ウィンドウにコンテンツを表示します。
最善の方法はPopup
、XAML で を定義しDataTrigger
てから、何らかの条件へのバインドを使用ViewModel
して非表示または表示することです。次に、 からの戻り値を処理したい場合はPopup
、EventTrigger
でプロパティをPopup
操作して、ViewModel
その変更を反映させます。
WinForms の世界では、人々がプログラミングに慣れているため、この種の分野について多くの話があります。初期データを取得したり設定したりする以外に、ビューにコードが必要な解決策をまだ見つけていませんDataContexts
ビューでイベント サブスクリプションを使用するのは良い選択ではないというカルロスの意見に同意します。私がMVVMを理解している限り、それはビューからコードビハインドを排除することにつながり、私はそれが本当に好きです:)。MVVM の長所の 1 つは、単体テストができることです。しかし、ウィンドウがポップアップしてもビューモデルをテストできると私は信じています。必要なのは、必要なビュー モデルで初期化された Content を使用して Window を使用することだけです。VM が新しいダイアログを開く必要がある場合、オプション/設定ウィンドウを表示するか、ビジネス ロジックに依存するウィンドウを表示するかの 2 つの状況が考えられると思います。最初のケースでは、新しいウィンドウ コードがコマンド (「設定」または「オプション」ボタン/メニュー項目のコマンド) の唯一のコードです。2 番目のケースでは、ウィンドウを開く意思決定ロジックがあります。ただし、いずれにしても、新しいウィンドウを開くコードを別のメソッド/クラスに移動し、VM をテストするときにこのメソッド/クラスをモックするだけです。さらに、この別のクラスは、アプリケーション内のすべてのウィンドウを追跡するある種の汎用 WindowsController にすることができます。ただし、ビュー モデルはヘルパー WindowsController を使用してポップアップを開き、ビューは他のウィンドウについて他に何も知らないと言えます。すべてのビジネス ロジックは、モデルとビュー モデルにカプセル化されたままです。
ポップアップ用の ViewModel とユーザー コントロールとしての View を用意します。ポップアップの複雑さに応じて、ユニバーサル VM またはビジネス ケースの具体的な VM のいずれかになります。親の VM から表示しようとする場合は、ポップアップの VM (Window または Popup から継承) の「ホスト」クラスを作成し、表示して VM をそれに割り当てます。ホストは、適切なビューを見つける責任を負う必要があります(DataTemplate を介して)
この場合、ポップアップの VM はまだテスト可能であり、親の VM の WPF との最小レベルの結合は許容されます (IMO)。