FC2ブログ

スポンサーサイト

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

ViewModelの型によってDataTemplateを変更する

 WPFでは同じViewModel(データ)であってもDataTemplateを変えることで異なる見た目にすることができます。
 基本的にはDataTemplateに名前を付けておいて、使用する際に使いたいDataTemplateの名前を指定します。
 大抵の場合はこの方法で何とかなりますが、例えば、ListBoxに表示する項目の見た目をデータによって変えたい場合などはこの方法は使用できません。
 この問題を解決する方法は2種類ありますが、今回はViewModelの型によって自動でDataTemplateを指定する方法を説明します。
 先ずはViewModelを用意します。
using Livet;
using System.Collections.ObjectModel;

namespace DataTemplate1.ViewModels
{
    public class MainWindowViewModel : ViewModel
    {
        public MainWindowViewModel()
        {
            Items = new ObservableCollection<ViewModel>();
            Items.Add(new ViewModelA());
            Items.Add(new ViewModelB());
        }

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

    public class ViewModelA : ViewModel
    {
        public ViewModelA()
        {
            Value = "ViewModelA";
        }

        public string Value { get; set; }
    }

    public class ViewModelB : ViewModel
    {
        public ViewModelB()
        {
            Text = "ViewModelB";
        }

        public string Text { get; set; }
    }
}
 ViewModelAとViewModelBの2つのViewModelを用意しました。
 次にViewのコードです。
<Window x:Class="DataTemplate1.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:DataTemplate1.Views"
        xmlns:vm="clr-namespace:DataTemplate1.ViewModels"
        Title="MainWindow" Height="130" Width="125">

    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
    
    <Window.Resources>
        <DataTemplate DataType="{x:Type vm:ViewModelA}">
            <Border BorderBrush="Red" BorderThickness="1">
                <TextBlock Text="{Binding Value}" Foreground="Red"/>
            </Border>
        </DataTemplate>
        
        <DataTemplate DataType="{x:Type vm:ViewModelB}">
            <Grid Background="Navy">
                <TextBlock Text="{Binding Text}" Foreground="White"/>
            </Grid>
        </DataTemplate>
    </Window.Resources>
    
    <StackPanel>
        <ListBox ItemsSource="{Binding Items}" />
        
        <ContentControl Content="{Binding Items[0]}"/>
        <ContentControl Content="{Binding Items[1]}"/>
    </StackPanel>
</Window>
 ResourcesにViewModelA用のDataTemplateとViewModelB用のDataTemplateを用意します。
 この時DataTemplateに名前は付けてはいけません。
 名前を付けないことでデータバインディングされているViewModelの型に合わせて自動的にDataTemplateが設定されます。
 このサンプルを実行すると以下の様になります。
DataTemplate1.png
 この機能はListBoxの様なコレクション系のコントロールだけが対象ではないので、単一のコントロールに対しても同様にDataTemplateが自動選択されます。
 おそらく一番簡単なDataTemplate設定方法なので、覚えておいて損はないと思います。
 次回は、もう一つの解決方法であるDataTemplateSelectorを使った方法を説明します。
スポンサーサイト

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

コメントの投稿

非公開コメント

カレンダー
10 | 2018/11 | 12
- - - - 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 -
全記事表示リンク

全ての記事を表示する

カテゴリ
タグリスト

月別アーカイブ
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ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。