WPF で動的にビューを切り替える
まずそもそもの話として、その「切り替え」がいわゆる画面遷移的なものだったら、
とりあえず NavigationService クラス (System.Windows.Navigation) を使っておくのが手軽でいい。
もちろん NavigationWindow クラス (System.Windows.Navigation) でもいいんだけど、
こっちは見た目のコントロールがちょっとめんどくさい。
WPFサンプル:NavigationServiceを使ったページ遷移:Gushwell's C# Dev Notes
NavigationWindowを使った画面遷移 - SourceChord
それ以外だととりあえず DataTemplate クラス (System.Windows) を使うことになるのかなと。
やってることは比較的シンプルで、
ContentControl.DataTemplate に、DataType に応じたビューを設定してるだけ。
ContentControl クラス (System.Windows.Controls) は任意のコントロールを表現することができるから、そこのテンプレートとして DataTemplate を指定する。
<Window.Resources> <DataTemplate DataType="{x:Type local:ViewModelA}"> <Button Content="{Binding Label}"/> </DataTemplate> <DataTemplate DataType="{x:Type local:ViewModelB}"> <CheckBox Content="{Binding Label}"/> </DataTemplate> </Window.Resources>
<ContentControl Content="{Binding ContentViewModel}" />
DataTemplate の扱いはちょっとだけややこしい。リソース上に複数のテンプレートが定義されているときに、ContentTemplate としてどのテンプレートが適用されるか。優先順位は以下の通り。
- ContentTemplate 側で指定したキーに一致するテンプレート
- オブジェクトの型が DataType に一致するテンプレート
まず、テンプレート側に明示的なキーが指定されていれば、オブジェクトの型によらずそれが適用される。
<Window.Resources> <DataTemplate x:Key="testKey"> <TextBlock Text="{Binding Label}"/> </DataTemplate> </Window.Resources>
<ContentControl Content="{Binding ContentViewModel}" ContentTemplate="{StaticResource testKey}"/>
そうでないときは「暗黙のキー」が指定されているということになって、DataType での型判定の結果次第で自動的にテンプレートが選ばれる。
このあたりは データ テンプレートの概要 を参照のこと。
この DataTemplate は、すべての Task オブジェクトに自動的に適用されます。 この場合、x:Key が暗黙的に設定されることに注意してください。 したがって、この DataTemplate に x:Key 値を割り当てる場合は、 暗黙の x:Key をオーバーライドします。 DataTemplate は自動的に適用されません。
同じ型のオブジェクトがバインドされてるときは、DataType でその型を指定しておいて、テンプレート内で DataTrigger を使って分岐すればいい。あとは、バインド先が TreeView だったりするときは DataTemplate じゃなくて HierarchicalDataTemplate を使うとか。
Style も x:Key と TargetType で適用先を指定できるけど、そっちも似たようなルールになってる。まずはキー指定を探して、なかったら TargetType で自動判定。