簡単な回答と要約:
お気づきのように、本当に必要なのは XAML から ViewModel をパラメーター化することです。したがって、私の本能は、ViewModel のパラメーターを渡す機能を提供するためにAttached Behaviorを作成することです。より具体的には、(a)必要な ViewModelと(b) その ViewModel のパラメーターの両方を指定できる単一のAttached Behavior クラスが必要であるということです。可能な限りDRYでありながら、単一のクラスでこれらの両方の欲求を満たすには、「ブレンド」動作を使用するのが最も簡単だと思います。なぜなら、ブレンド動作は静的クラスではないため、それらを使用できる方がはるかに簡単だと思われるからです。両方の関連情報を一緒に渡します。
説明:
最初の簡単な免責事項: MEFedMVVM や Prism を使用したことはありません (ただし、他の MVVM ライブラリを使用したことはあります)。したがって、このアプローチは、「通常の」方法 (つまり、DataContext を自動的に接続するなど) で物事を使用するときに Prism が提供する可能性のある「魔法の」ものに依存しないため、この考え方を組み立てましょう。
「通常の」アタッチされた動作と「ブレンド」動作の違いについての良い記事については、このブログ投稿が気に入っています。ここで彼の説明を繰り返すことはしませんが、私が気付いた重要なことは、通常の添付ビヘイビアーは、その機能を実行するために単一の情報 (つまり、単一の「パラメーター」) に依存しているように見えるということです。など(ブログ投稿から):
<GridView local:ItemClickNavBehavior.Destination="Home" ...>
これをあなたのケースに当てはめて、通常のAttached Bahaviorsを使用した場合にどのように機能するかを調べてみましょう。Attached Behavior クラスを作成し、それを「MyViewModel1Creator」と呼びます。
(1)「Type」という添付プロパティを登録し、
(2)「Type」の変更コールバック ハンドラーを含めます (初期設定時にも呼び出されます - リンクされたブログ投稿の「HookupBehavior」メソッドを参照してください)。この変更コールバックでは、「ViewModel1」をインスタンス化し、それに「Type」添付プロパティの値を渡します。また、このメソッドでは、ビューの DataContext の設定など、その他の必要事項を処理できます。コールバック ハンドラ (Dependency オブジェクト パラメータ)。
次に、「MyViewModel1Creator」クラスの Xaml の使用は次のようになります。
<views:MyView x:Name="view1" MyBehaviors:MyViewModel1Creator.Type="X" />
<views:MyView x:Name="view2" MyBehaviors:MyViewModel1Creator.Type="Y" />
これは機能しますが、このアプローチには欠点があります(通常の添付プロパティを使用)。このアプローチを使用するには、ViewModel ごとに個別の Attached Behavior クラスを作成する必要があります。つまり、3 つの ViewModel ("ViewModel1"、"ViewModel2"、"ViewModel3") がある場合は、3 つの Attached Behavior クラス ( "ViewModel1Creator"、"ViewModel2Creator"、"ViewModel3Creator")。それぞれがそれぞれの ViewModel をインスタンス化します (そして、上記のように "Type" 添付プロパティを公開します)。もう 1 つの欠点は、渡すパラメーターを 追加する方法を見つけるのが難しいように思われることです。
上記の方法とは少し異なるアプローチですが、 DRYであるという点では同様に不十分ですが、「CreateViewModel_1_WithType」のような名前の複数の添付プロパティを格納する単一のクラス (「MyViewModelCreator」と呼びます。今回は「1」は付けません) を使用します。 "、"CreateViewModel_2_WithType"、"CreateViewModel_3_WithType" など。使用方法は次のようになります。
<views:MyView x:Name="view1"
MyBehaviors:MyViewModelCreator.CreateViewModel_1_WithType="X" />
<views:MyView x:Name="view2"
MyBehaviors:MyViewModelCreator.CreateViewModel_1_WithType="Y" />
繰り返しますが、これらのアプローチはあまり DRY ではないため、本当に必要なのは...
次に、 「ブレンド」動作を使用した場合にどのように機能するかを考えてみましょう:
型指定された Behavior から派生するクラスを作成します。ビューの場合はおそらく になるBehavior<UserControl>
ため、クラスの見出しは次のようになります
public class ViewModelSetupBehavior : Behavior<UserControl>
。このクラスでは、(1) "Type" 依存関係プロパティと "ViewModelName" 依存関係プロパティを含む、必要な数の依存関係プロパティを登録し、(2)OnAttached()
どちらの ViewModel もインスタンス化するメソッドをオーバーライドします。「ViewModelName」依存プロパティの値によって示され、「Type」依存プロパティの値もそれに渡します。繰り返しますが、これは、ビューの DataContext の設定など、その他の必要性も処理する場所になります。ビヘイビアーが「アタッチされている」オブジェクトにアクセスできます。AssociatedObject
財産。
これにより、次のことが可能になります。
<views:MyView x:Name="view1">
<i:Interaction.Behaviors>
<MyBehaviors:ViewModelSetupBehavior ViewModelName="ViewModel1" Type="X" SomeOtherParam="bla" />
</i:Interaction.Behaviors>
</views:MyView>
<views:MyView x:Name="view2">
<i:Interaction.Behaviors>
<MyBehaviors:ViewModelSetupBehavior ViewModelName="ViewModel1" Type="Y" />
</i:Interaction.Behaviors>
</views:MyView>
ここで、単一のBehavior クラスを使用してすべての ViewModel を作成できることに注意してください。いくつかのパラメーターを渡して、ViewModel をインスタンス化する方法を指定できます。