#はじめに
ツール開発に関して自分のなかである程度知識がまとまってきたので、
ちょっと高度な?MVVMについてに記述していきます。
今回やること
下の用な感じでタブコントロールの中身をスマートに変更できるようプログラム作っていきます。
タブコントロールの作成
<UserControl.Resources>
<vm:DockPaneTemplateSelector x:Key="TabItemTemplateSelector">
<vm:DockPaneTemplateSelector.ShaderProgramTemplate>
<DataTemplate DataType="{x:Type vm:ShaderProgramViewModel}">
<v:ShaderProgramView/>
</DataTemplate>
</vm:DockPaneTemplateSelector.ShaderProgramTemplate>
<vm:DockPaneTemplateSelector.VoxelTemplate>
<DataTemplate DataType="{x:Type vmc:VoxelViewModel}">
<vc:VoxelView/>
</DataTemplate>
</vm:DockPaneTemplateSelector.VoxelTemplate>
<DataTemplate x:Key="TabItemHeaderTempalte">
<DockPanel>
<TextBlock Text="{Binding Title}" DockPanel.Dock="Left"/>
<Button Content=" x " Command="{Binding CloseTabItem}" DockPanel.Dock="Right" Background="White"/>
</DockPanel>
</DataTemplate>
</UserControl.Resources>
<TabControl ItemsSource="{Binding ItemsSource}" SelectedItem="{Binding ActiveItem}" ContentTemplateSelector="{StaticResource TabItemTemplateSelector}" ItemTemplate="{StaticResource TabItemHeaderTempalte}"/>
public class TabControlViewModel : DockWindowViewModel
{
private TabItemViewModel _activeItem;
public TabItemViewModel ActiveItem
{
get
{
return _activeItem;
}
set
{
SetValue(ref _activeItem, value);
}
}
private ObservableCollection<TabItemViewModel> _ItemsSource = new ObservableCollection<TabItemViewModel>();
public ObservableCollection<TabItemViewModel> ItemsSource
{
get
{
return _ItemsSource;
}
set
{
SetValue(ref _ItemsSource, value);
}
}
public TabControlViewModel()
{
}
}
class DockPaneTemplateSelector: DataTemplateSelector
{
public DataTemplate ShaderProgramTemplate { get; set; }
public DataTemplate VoxelTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is ShaderProgramViewModel)
{
return ShaderProgramTemplate;
}
if(item is VoxelViewModel)
{
return VoxelTemplate;
}
return base.SelectTemplate(item, container);
}
}
こんな感じです。
まずはC#のほうではDataTemplateSelectorを継承しDockPaneTemplateSelectorを定義します。
これでItemsSourceに値が追加されると、Itemの型を参照し、
ShaderProgramViewModelが追加されたんだったらShaderProgramTemplate使ってねと指定できます。
次にxamlのほうです。
一番の注目はContentTemplateSelectorです。
ここでUserControl.Resourceに書いたTabItemTempalateSelectorをBindingしています。
ここで、ShaderProgramTemplateならShaderProgramViewを表示してね
追加されたItemの型はShaderProgramViewModelだよと指定できます。
ちなみにVoxelViewとShaderProgramViewはUserControlです。あとはコントロール配置してるだけです。
#最後に
DataTemplateSelectorの他にStyleSelectorなるものもあります。
表示するViewModelによってStyleを変更したいときに使えるようです。
このあたり使えるようになるとツール開発やりやすくなってくると思います。