3

私のSilverlightアプリケーションでは、ユーザーはフォームの複数のテンプレートを作成できます。選択したテンプレートに応じて、フォームには特定の順序で一連のビューが表示されます。さらに、一部のビューは、テンプレートに存在する場合は「必須」です。クライアントは、そのようなビューをポップアップフォームに表示することを望んでいるため、ユーザーは、フォーム上の他のビューに移動する前に、まずこれらの「必要な」ビューだけに焦点を合わせます。

今、私はこの要件のMVVMパターンを破っています。理由は次のとおりです...1。ViewModelはデータベースからテンプレートを読み取り、ビューを(MEFを使用して)取得できますが、フォームに追加するには、レイアウトグリッドの名前を認識し、子としてビューを追加する必要があります。そのグリッド。これは、MVVMデザインパターンに反するUI要素についてViewModelに通知するようなものです。

  1. ポップアップに表示する必要のある「必須」ビューの場合、viewModelはChildWindowインスタンスを作成し、それに「必須」ビューを追加してから、Childwindowを表示する必要があります。クローズ/クローズイベントも処理します。

私のアプローチには欠陥があると確信していますが、ここでUIロジックをビジネスロジックから明確に分離する方法を見つけることはできません。誰かがより良いアプローチを提供できますか?

ありがとう。A

4

3 に答える 3

3

IMHO: これは、コントローラーを MVVM に追加するだけですべての問題がきれいに解決される、もう 1 つの状況です。私たちはそれを MVCVM と呼んでいます (有効なローマ数字と同等ではない恥) :)

最近のすべてのプロジェクトで成功しているパターンは、コントローラーのみをモジュールに登録し、起動時にそれらを初期化することです。コントローラーは非常に軽量/スリムで、メッセージをリッスンまたは送信するアプリの存続期間中、ぶらぶらする必要がある唯一のものです。初期化メソッドでは、所有する必要があるもの (ビューやビューモデルなど) を登録します。この軽量なメモリ内ロジックのみのパターンは、よりスリムなアプリにもなります (たとえば、WP7 の方が適しています)。

あなたが見つけたように、VM を使用するだけの問題は、最終的にビューについて知る必要があるケースに遭遇することです (これは、決して知ってはならないことの 1 つです)。

私たちが従う基本的なルールは次のとおりです。

  • コントローラーはイベントに基づいて決定を下します
  • コントローラーはデータを取得し、適切なビュー モデル プロパティに配置します。
  • コントローラーは、ビュー モデルの ICommand プロパティを設定して、イベントを傍受します
  • コントローラーはビューを表示します (他の場所で暗示されていなければ)
  • ビューモデルは「ばか」です。バインド用のホールド データのみ
  • ビューは、特定の形式のデータを表示することを認識していますが、それがどこから来たのかはわかりません

最後の 2 つのポイントは、絶対に破ってはならないものです。

これまでのところ、VM がデータベースに直接アクセスする必要があり (悪い)、VM がビューを取得し (非常に悪い)、VM が別のウィンドウをポップアップする必要がある (非常に悪い) 必要があります。

少し考えてみてください。MVVM アプリにコントローラーを (再) 導入することになるかもしれません。さらに詳しい情報が必要な場合は、お尋ねください。

于 2011-07-30T16:41:43.783 に答える
0

これが私の頭に浮かぶ解決策です。

1. ViewModel が関連付けられている View 名を持つメタタグで ViewModel を装飾します。

  1. 2 つのプロパティを保持する ViewViewModel という新しいクラスを作成します。

    • ビュー名
    • ViewModel インスタンス。
  2. フォーム ViewModel では、すべてのビューをまとめて集約し、場合によっては子ウィンドウも表示します。3 つのプロパティを追加する

    • FormView の一覧表示
    • ChildWindowView を一覧表示します。
    • アクション ShowChildWindow

FormView モデルは、必要なビューモデルをインスタンス化し、MEF メタタグから各ビューモデルのビュー名を収集し、FormView および ChildWindowView プロパティを設定します。フォーム ViewModel がリクエストの処理を完了し、2 つのプロパティが入力されると、ChildWindow が空でない場合は true パラメータで ShowWindow デリゲートを起動します。

  1. フォームビューは次のことを行います

    • レイアウト ルートには、FormView プロパティにバインドされたスタックパネルがあります。FormViews List の各エントリを処理する IValueConverter があります。ViewName ごとに、ビューのインスタンスを検索して作成します。DataContext を ViewModel に設定します。

    • ShowChildWindow アクションが発生すると、フォーム ビューには最小限のコード ビハインドがあり、ChildWindowViews プロパティにバインドされた ChildWindow を作成して表示します。ChildWindow プロパティは、同じ IValueCONverter を使用して、要求されたビューのインスタンスを作成します。

それはどのように聞こえますか?コメントをお願いします

enter code here
于 2011-07-31T03:39:39.947 に答える
0

私たちのプロジェクトでは、UI 固有の処理が必要なときにビューとビュー モデルの間で通信する必要がある場合、イベント サブスクリプション メカニズムに従っています。問題を解決する 1 つの方法は、ビューのリストをイベント引数としてビュー モデルにイベントを発行することです。または、このリストを維持し、ビュー モデルに設定され、プロパティが更新されたときにイベントが発生するプロパティが存在する可能性があります。ビューでは、イベントをサブスクライブして、コントロールをレイアウト ルートに追加できます。これはテスト可能なソリューションであり、ビュー モデルにビュー固有のものは何も配置しません。

MVVM フレームワークを自由に使用できる場合は、PRISM や MVVMLight などを試すことができます。Prism はイベント アグリーゲーターを提供し、MVVMLight は、ビューとビュー モデル、および異なるビュー モデル間の通信を切り離すことができる Messenger クラスを提供します。

于 2011-07-31T01:04:42.647 に答える