私は、地域のポイントが何であるか疑問に思っています。私は彼らが解決する問題を理解していないと思います。
たとえば、多くの人がナビゲーション領域に領域を使用しているのを目にしますが、領域を持つ代わりに、ItemsControl を ObservableCollection にバインドし、さまざまなナビゲーション要素をその領域にロードしないのはなぜでしょうか?
代替案に対するその使用/利点の実例は驚くべきものです!
私は、地域のポイントが何であるか疑問に思っています。私は彼らが解決する問題を理解していないと思います。
たとえば、多くの人がナビゲーション領域に領域を使用しているのを目にしますが、領域を持つ代わりに、ItemsControl を ObservableCollection にバインドし、さまざまなナビゲーション要素をその領域にロードしないのはなぜでしょうか?
代替案に対するその使用/利点の実例は驚くべきものです!
リージョンを使用すると、特定の目的のために存在するプログラム内のスポットを定義できます。たとえば、メニュー領域やフッター領域があるとします。次に、これらの特定の領域の Views/ViewModels をプログラムの独自のセクションに分離できます。
そのため、とApplicationViewModel
のプロパティを含むようにし、ビューに各セクションをそれらのプロパティにバインドさせる代わりに、メニューとフッターに個別の ViewModel を用意し、ApplicationViewModel はコンテンツのみを処理します。アプリケーション内のいくつかの論理境界を分離するためのより良い方法です。MenuViewModel
FooterViewModel
個人的には、リージョンはひどく乱用され、乱用されていると思います。残りのアプリケーション コードとは関係のないヘッダーやフッターのようなものがない限り、ほとんど使用しません。これらは主に View-First 開発でも使用されますが、私は ViewModel-First を好みます。
RegionManagerをEventAggregatorと比較すると、その利点がわかります...
EventAggregatorを使用すると、さまざまなコンポーネントを相互に結合せずにイベントをパブリッシュ/サブスクライブできます。同じことがRegionManagerにも当てはまります...他のビューがそこで何が起こっているかを知らなくても、ビューをリージョンにロードできます。それはあなたのビューを互いに切り離します...それはすべてのビューがお互いに気づいてはいけないということではありません...ビューが別のビューについて知っているべき時があります。
Microsoft Outlookを見てください(注:OutlookはWPFではなく、C ++で記述されているため、名前も含めてここで作成しています):
メインUIには次のリージョンがあります。
リージョンは標準コントロールで定義されます(したがって、引き続き標準コントロールが必要です)。具体的には、ItemsControl、ContentControl、およびSelectorをそのまま使用できます(他のコントロールを拡張して「リージョンをサポート」することができます)。これらは、コードの別のセクションが適切なビューを解決してそれらの領域にロードすることにより、領域を管理できるようにします。基本的に、物事を切り離しておくために。
メインUIは、アプリケーションに関するすべてを知る必要はありません。代わりに、メニュー、ナビゲーション、コンテンツ、およびサイドリージョンがあることを知る必要があります。実際にリージョンに配置されているビューは関係ありません。さて、それはすべてのビューが互いに分離されるべきだという意味ではありません。後で説明します。
それで、それは実際にどのように分離しますか?シナリオは次のとおりです。ナビゲーションコントロールのカレンダーアイコンをクリックします。それで、あなたがそれをするとき、何が起こるべきですか?
NavigationView
-ボタン(アイコン)はにバインドされているICommand
ため、関数を呼び出しExecuteLoadCalendar()
ます。NavigationViewModel
-このExecuteLoadCalendar()
関数は、EventAggregator
を使用して、ユーザーがカレンダーを起動しようとしていることを通知します。ContentController
-ContentController
がサブスクライブしていたLoadCalendarAggregateEvent
ので、実行されます。ここでは、とリージョン名を使用してCalendarView
(COUPLED)を解決/アクティブ化します。の代わりにグラブすることでこれを行う必要があります。IRegionManager
ICalendarView
CalendarView
ContentController
プロセス全体を通して、とCalendarView
/を除いて、各部分は分離されICalendarView
ます。もちろん、/は、and関数を持っていることでNavigationView
/NavigationViewModel
について知っていたと言えます。コードビハインドコードとビューモデルコードが実際の/オブジェクトを参照してはならないため、「種類」は「それらが行う」と同じではありません。CalendarView
CalendarViewModel
ICommand
CalendarView
CalendarViewModel
また、executeをジェネリックにすることで、「一種の」を削除できます。ExecuteLoadCalendar()
関数を持つ代わりに、たとえばLoadContent(NavigationItem item)
、ペイロードが(DB、XMLなどからロードされた)AggregateEvent
ある種のIDであり、 「カレンダー」をクリックしたことを示す関数を持つことができます。item.Name (String)
は、のContentController
代わりに「カレンダー」を解決するために同じデータを使用しますICalendarView
(実際には、どのインターフェイス/タイプが解決/アクティブ化されるかを気にする必要がないため、アクティブ化するにContentRegion
はオブジェクトが必要です)。私はMEFを使用しているので、これは次のコードブロックで実現できます。
[Export("Calendar")]
public class CalendarView : UserControl, ICalendarView { }
それで、ビューはお互いについて知ることができますか?はい!たとえばEmailUserControl
、検索バー/メールのリストとプレビューペインがあります。これらの2つのコントロールはEmailListUserControl
、検索バーとItemsControlで構成される、とEmailContentUserControl
、選択した電子メールの単なるプレビューペインであるになります。それらは別々のコントロールである必要がありますか?EmailContentUserControl
いいえ。ただし、そうである場合は、別のウィンドウでメールを開いたときにを再利用できます。したがって、これは、が2つの異なるビュー(および)EmailUserControl
に結合されている例です。EmailListUserControl
EmailContentUserControl
これが他のアプローチと異なる/優れている理由:ビューを相互に分離します(ビューモデルがビューについて知る必要があるのを防ぎます)。
地域が可能にするシナリオ
答えを得るためにこの記事をざっと読みました: http://www.developmentalmadness.com/archive/2009/10/14/mvvm-and-prism-101-ndash-part-3-regions.aspx
私が知る限り、リージョン機能は、ビューでもビューモデルでもないコードでビューの登録/インジェクションを有効にするように設計されています。
ContentPresenter
コントロールを例にとってみましょう。リージョンの代わりにそれを使用した場合、メイン ビューをその子ビューにとらわれないようにするために、ビュー モデルは具体的なビューを返す必要があります。
を使用ItemsControl
してビュー モデルの任意のデータにバインドした場合、メイン ビューの DataTemplate でインスタンス化するビューを指定する必要があります。
Region を使用すると、ビューをDependency Injectionコンテナーの Region に登録できます。ビューも対応するビュー モデルも、実行時に使用される具体的なビューについて何も知る必要はありません。容器ごと注入されます。
これにより、ビュー モデルに子ビューに関する情報を強制することなく、メイン ビューをその子ビューに関する情報から完全に切り離すことができます。
具体的なユースケース
これがどれほど便利で、どのような具体的なシナリオが可能になるかはわかりません。プラグイン アーキテクチャでを使用しましたContentPresenter
が、このモデルにうまく適合するかどうかはわかりません。プラグイン モデルでは、ビューとビュー モデルを結合する必要があるため、このアプローチでは何も得られません。
無関係な大きなビューがあり、それらを分割したい場合に最適だと思います。一度にビューとビュー モデルの一部のみを注入することで、統合テストを互いに分離するのに役立つ場合があります。
私は説得力のある実世界のユースケースのストローを把握しています:)ほとんどすべてのケースで、UserControl
代わりに単に a を使用することができ、動的登録全体を放棄することができ、実際のマイナス面はありません.