FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

DataTemplateSelectorを使用してDataTemplateを選択する

 今回はDataTemplateSelectorを使用してDataTemplateを選択する方法を説明します。
 DataTemplateSelectorを使用する場合は、ViewModelのプロパティの値を元にどのDataTemplateを使用するかを判断します。
 先ずはViewModelを作成します。
using Livet;
using System.Collections.ObjectModel;

namespace DataTemplate2.ViewModels
{
    public class MainWindowViewModel : ViewModel
    {
        public MainWindowViewModel()
        {
            Items = new ObservableCollection<ItemViewModel>();
            Items.Add(new ItemViewModel() { Type = "1", Value = "Type1" });
            Items.Add(new ItemViewModel() { Type = "2", Value = "Type2" });
        }

        public ObservableCollection<ItemViewModel> Items { get; private set; }
    }

    public class ItemViewModel : ViewModel
    {

        #region Value変更通知プロパティ
        private string _Value;

        public string Value
        {
            get
            { return _Value; }
            set
            { 
                if (_Value == value)
                    return;
                _Value = value;
                RaisePropertyChanged();
            }
        }
        #endregion


        #region Type変更通知プロパティ
        private string _Type;

        public string Type
        {
            get
            { return _Type; }
            set
            { 
                if (_Type == value)
                    return;
                _Type = value;
                RaisePropertyChanged();
            }
        }
        #endregion

    }
}
 今回はItemViewModelのTypeプロパティの値を元にDataTemplateを選択します。
 次にDataTemplateSelectorを作成します。
using DataTemplate2.ViewModels;
using System.Windows;
using System.Windows.Controls;

namespace DataTemplate2.Selector
{
    /// <summary>
    /// ItemViewModelのデータテンプレートセレクター
    /// </summary>
    public class ItemViewModelDataTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            var element = container as FrameworkElement;
            var viewModel = item as ItemViewModel;
            if (element == null || viewModel == null) return null;

            var templateName = "";
            switch (viewModel.Type)
            {
                case "1": templateName = "Type1DataTemplate"; break;
                case "2": templateName = "Type2DataTemplate"; break;
                default: templateName = ""; break;
            }

            return templateName == ""
                ? null
                : element.FindResource(templateName) as DataTemplate;
        }
    }
}
 ItemViewModel用のデータテンプレートセレクターを作成します。
 セレクターはDataTemplateSelectorを継承し、SelectTemplateメソッドをオーバーライドする必要があります。
 SelectTemplateメソッドでViewModelのプロパティを元にどのDataTemplateを使用するかを判断し、使用するDataTemplateを返します。
 ここではTypeプロパティの値によってDataTemplateを選択しています。
 DataTemplateはFindResourceメソッドを使用して取得できます。(View側でDataTemplateが定義されている必要があります)
 最後にViewのコードです。
<Window x:Class="DataTemplate2.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
        xmlns:v="clr-namespace:DataTemplate2.Views"
        xmlns:vm="clr-namespace:DataTemplate2.ViewModels"
        xmlns:selector="clr-namespace:DataTemplate2.Selector"
        Title="MainWindow" Height="90" Width="125">
    
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
    
    <Window.Resources>
        <selector:ItemViewModelDataTemplateSelector x:Key="ItemViewModelTemplateSelector"/>
        
        <DataTemplate x:Key="Type1DataTemplate" DataType="{x:Type vm:ItemViewModel}">
            <Border BorderBrush="Red" BorderThickness="1">
                <TextBlock Text="{Binding Value}" Foreground="Red"/>
            </Border>
        </DataTemplate>

        <DataTemplate x:Key="Type2DataTemplate" DataType="{x:Type vm:ItemViewModel}">
            <Grid Background="Navy">
                <TextBlock Text="{Binding Value}" Foreground="White"/>
            </Grid>
        </DataTemplate>
    </Window.Resources>
    
    <StackPanel>
        <ListBox ItemsSource="{Binding Items}"
                 ItemTemplateSelector="{StaticResource ItemViewModelTemplateSelector}"/>
    </StackPanel>
</Window>
 ResourcesでDataTemplateを定義します。
 また、使用するデータテンプレートセレクターを用意しておきます。
 データテンプレートセレクターを使用する場合は、コントロールのItemTemplateSelectorに使用したいデータテンプレートセレクターを指定してください。
 このコードを実行すると以下の様になります。
DataTemplate2.png
 データテンプレートセレクターによるDataTemplate選択はデータバインディングされた際に行われるようです。
 そのため、あとからプロパティを変更してもDataTemplateは変更されません。
 DataTemplate1→DataTemplate2の様に後からDataTemplateを切り替えたい場合はトリガーを使用してDataTemplateを変更してください。
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

カレンダー
11 | 2018/12 | 01
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -
全記事表示リンク

全ての記事を表示する

カテゴリ
タグリスト

月別アーカイブ
11  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  04  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  11  10  09 
最新記事
リンク
最新コメント
検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。