LoginSignup
4
2

More than 5 years have passed since last update.

DataTemplateで要素の切り替え

Last updated at Posted at 2016-12-03

はじめに

ツール開発に関して自分のなかである程度知識がまとまってきたので、
ちょっと高度な?MVVMについてに記述していきます。

今回やること

下の用な感じでタブコントロールの中身をスマートに変更できるようプログラム作っていきます。
image

タブコントロールの作成

TabControlView.xaml
     <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}"/>

TabControlViewModel.cs

    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を変更したいときに使えるようです。

このあたり使えるようになるとツール開発やりやすくなってくると思います。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2