[解決済み] ViewModelLocatorとは何ですか?また、DataTemplatesと比較した場合の長所と短所は何ですか?
質問
ViewModelLocator とは何か、どのように機能するのか、DataTemplates と比較して、それを使用することの長所と短所を簡単にまとめてくれる人はいますか?
私はGoogleで情報を見つけようとしましたが、それの多くの異なる実装とそれが何であるか、それを使用することの長所/短所に関する明確なリストがないようです。
どのように解決するのですか?
導入
MVVM では、通常、View はビューモデルを 依存性注入 (DI) コンテナから解決することによって ViewModel を見つけさせることです。これは、コンテナがViewクラスのインスタンスを提供(解決)するように要求されたときに自動的に発生します。コンテナは を注入します。 を注入し、ViewModel のパラメータを受け入れる View のコンストラクタを呼び出すことで、View に ViewModel を注入します。このスキームは 制御の反転 (IoC) と呼ばれます。
DI のメリット
ここでの主な利点は、コンテナを構成することができることです。 を実行時に設定できることです。 を設定できることです。これにより、アプリケーションが実際に実行されるときには使用する型 (Views と ViewModels) を解決するように指示し、アプリケーションのユニット テストを実行するときには別の方法で指示することで、より高いテスト容易性を実現できます。後者の場合、アプリケーションには UI がありません (アプリケーションは実行されず、テストだけが実行されます) ので、コンテナは モック を、アプリケーションの実行時に使用される "normal" タイプの代わりに解決します。
DIに起因する問題
これまで、DIのアプローチでは、アプリケーションコンポーネントの作成に抽象化レイヤーを追加することで、アプリケーションのテスト容易性を高めることができることを見てきました。このアプローチには1つ問題があります。 ビジュアルデザイナーと相性が悪い。 Microsoft Expression Blendのようなビジュアルデザイナーとは相性が悪いのです。
問題は、通常のアプリケーションの実行とユニットテストの実行の両方において、誰かが をセットアップする必要があります。 を設定し、さらに、誰かが を尋ねます。 さらに、ViewModels を View に注入できるように、コンテナが View を解決するよう、 コンテナに依頼する必要があります。
しかし を実行する私たちのコードはありません。 . デザイナーはリフレクションを使用して私たちのViewsのインスタンスを作成しようとします。
- View のコンストラクタが ViewModel のインスタンスを必要とする場合、デザイナーは View を全くインスタンス化することができず、何らかの制御された方法でエラーになります。
-
View がパラメータなしのコンストラクタを持つ場合、View はインスタンス化されますが、その
DataContext
はnull
であるため、デザイナーに "empty" というビューが表示され、これはあまり便利ではありません。
ViewModelLocator の入力
ViewModelLocator は、このように使用される追加の抽象化です。
- View 自身が、ViewModelLocator をその リソース の一部としてインスタンス化し、その DataContext をロケータの ViewModel プロパティにデータ転送します。
- ロケータはどういうわけか デザインモードであるかどうかを検出する
- デザインモードでない場合、ロケータは上記で説明したようにDIコンテナから解決したViewModelを返します。
- 設計モードの場合、ロケーターは独自のロジックを使用して固定された "ダミー" ViewModel を返します (設計時にはコンテナーは存在しないことを思い出してください!); この ViewModel には通常、ダミー データが事前に入力されます。
もちろん、これは、View が最初にパラメータなしのコンストラクタを持たなければならないことを意味します (さもなければ、デザイナーはそれをインスタンス化することができません)。
概要
ViewModelLocator は、MVVM アプリケーションで DI の利点を維持しながら、コードがビジュアルデザイナーとうまく連携できるようにするためのイディオムです。これは、アプリケーションのブレンド性(Expression Blendを参照)と呼ばれることもあります。
上記を理解した後、実用的な例をご覧ください。 ここで .
最後に、データテンプレートの使用は ViewModelLocator の代替ではなく、UI の一部に明示的な View/ViewModel のペアを使用するための代替となります。しばしば、ViewModel のために View を定義する必要がないことに気づくかもしれませんが、それは代わりにデータテンプレートを使うことができるからです。
関連
-
[解決済み] WPFの場合、x:Name属性とName属性の違いは何ですか?
-
[解決済み] Windows 8 ランタイム(WinRT / Windowsストアアプリ / Windows 10 ユニバーサルアプリ)とSilverlightやWPFの比較はどうですか?[クローズド]
-
[解決済み】INotifyPropertyChangedとViewModelのDependencyPropertyの比較
-
[解決済み】Visual Studio 2015の追加デバッグオプションの無効化
-
[解決済み] wpf: ボタンがコマンドによって無効にされたとき、ツールチップを表示する方法は?
-
[解決済み] WPF: グリッドに列/行のマージン/パディングを設定できますか?
-
[解決済み] WPF Numeric UpDownコントロールはどこにありますか?
-
[解決済み] WPF: スクロールバー付きItemsControl (ScrollViewer)
-
[解決済み] データバインディングでWPFハイパーリンクのテキストを設定するにはどうすればよいですか?
-
[解決済み] 読み取り専用のGUIプロパティをViewModelにプッシュバックする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
例外の解決方法 GDI+でジェネリックエラーが発生しました。
-
[解決済み] 静的プロパティへのバインディング
-
[解決済み] オーバーレイコントロールを他のすべてのコントロールの上に配置するには?
-
[解決済み] WPFでイベント処理のためにリソース辞書の後ろにコードを設定することは可能ですか?
-
[解決済み] WPF Numeric UpDownコントロールはどこにありますか?
-
[解決済み] 16進数の色値からSolidColorBrushを作成する
-
[解決済み] Prism for WPFとは?
-
[解決済み] WPFのキーボードショートカット
-
[解決済み] 読み取り専用のGUIプロパティをViewModelにプッシュバックする
-
[解決済み] ViewModelLocatorとは何ですか?また、DataTemplatesと比較した場合の長所と短所は何ですか?