Prism 別名 CompositeWpf でのモジュールとアプリケーションの統合
-
13-09-2019 - |
質問
から MSDN:
おそらく、モジュール内のほとんどのビューは直接表示する必要はなく、ユーザーによる何らかのアクションがあった後にのみ表示されます。アプリケーションのスタイルによっては、ユーザーがビューにアクセスするためにメニュー、ツールバー、またはその他のナビゲーション戦略を使用することが必要になる場合があります。モジュールの初期化メソッドでは、アプリケーションのナビゲーション構造に登録することもできます。ナビゲーション構造のイベント ハンドラー (つまり、ユーザーがメニュー項目をクリックしたとき) では、ビュー挿入テクニックを使用して、適切な領域にビューを追加できます。
私も同様のシナリオを持っており、RegisterViewWithRegion を使用してモジュールの初期化メソッドでビューをリージョンに追加しています。メニュー (別のモジュール) とのビュー ベースのユーザー インタラクションを表示したいと考えています。
Prism のモジュールの分離された動作を壊さずにこの動作を実現するにはどうすればよいですか?
たとえば、ModuleB から ModuleA によってリージョンに追加されたビューをアクティブ化/表示することは可能ですか?
解決
私が行うことは、次のインターフェイスを使用してシェル内にビュー レジストリを作成することです (ここでは簡略化しています)。
public interface IViewRegistry
{
void RegisterView(string title, string key, Func<UIElement> viewCreationMethod);
void OpenView(string key);
}
これは単純化しすぎですが、イメージがつかめれば幸いです。各モジュールは、初期化時にこのインターフェイスを使用してそのビューをシェルに登録します。私のシェルでは、これらのものを保存する ViewStore を作成します。
public static class ViewStore
{
public Dictionary<string, ViewEntry> Views { get; set; }
static ViewStore()
{
Views = new Dictionary<string, ViewEntry>();
}
public void RegisterView(string name, string key, Func<UIElement> createMethod)
{
Views.Add(key, new ViewEntry() { Name = name, CreateMethod = createMethod });
}
}
次に、IViewRegistry 実装から:
public class ViewRegistryService : IViewRegistry
{
public void RegisterView(string title, string key, Func<UIElement> createMethod)
{
ViewStore.RegisterView(title, key, createMethod);
}
public void OpenView(string key)
{
//Check here with your region manager to see if
//the view is already open, if not, inject it
var view = _regionManager.Regions["MyRegion"].GetView(key);
if(view != null)
{
view = ViewStore.Views[key]();
_regionManager.Regions["MyRegion"].Add(view, key);
}
_regionManager.Regions["MyRegion"].Activate(view);
}
private IRegionManager _regionManager;
public ViewRegistryService(IRegionManager rm)
{
_regionManager = rm;
}
}
今、私には2つのことがあります:
- シェルでメニューを作成するために使用できる ViewStore。
- モジュールが、単純な ModuleDependency を超えた結合を行わずに、他のモジュールが所有するビューを開く方法 (実際には、ModuleDependency さえも必要ありませんが、おそらく正しいです。)
明らかに、この方法では物事が単純化しすぎます。ビューをメニュー項目にするかどうかを示すものがあります。私のアプリにはいくつかのメニューなどがありますが、これが基本であり、すぐに使えるはずです。
また、Stackoverflow に答えを得る機会を少し与える必要があります...諦めるまでに3時間しか与えてくれなかった:)
お役に立てれば。
他のヒント
RegisterViewWithRegion には、ビュー名をパラメータとして受け入れるオーバーロードがありません。これにより、モジュールの統合が容易になった可能性があります。に作業項目を追加しました コードプレックス
現在、ビューインジェクション用に他のモジュールへの参照を追加しており、Prism の疎結合の性質を失っています。