2013年07月18日

WPFサンプル:DataTemplateでカスタムクラスのデータの表示形式を定義する

   このエントリーをはてなブックマークに追加 Clip to Evernote
前回は、DateTimeの表示形式をDataTemplateで定義しましたが、今度はカスタムクラスの表示をDataTemplateで定義してみます。

以下のようなカスタムクラスを定義します。
サンプルが複雑にならないように、2つのプロパティを持つ簡単なクラスとしました。

public class MyImage {
    public string Name { get; set; }
    public BitmapImage Bitmap { get; set; }
}

このクラスに対するDataTemplateを定義し、その中で、Nameプロパティと、Bitmapプロパティをバインド指定します。
今回は、利用するコントロールをContentControlとしました。このコントロールは、コンテンツを持つコントロールの基底クラスで、独自のコントロールを定義する場合や、DataTemplateを使った表示のみを行う場合などに利用できます。

<Window x:Class="DataTemplateSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:local="clr-namespace:DataTemplateSample"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:MyImage}">
            <StackPanel Name="stackPanel1" Orientation="Horizontal">
                <Image Height="80" Stretch="Uniform" Source="{Binding Bitmap}"/>
                <Label Content="{Binding Name}" FontSize="14" VerticalAlignment="Center"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ContentControl Name="myImage" Content="{Binding}" Height="80" />
    </Grid>
</Window>

C#側のコードは、MyImageオブジェクトを生成し、myImageのDataContextに設定しているだけです。
どのような形式で表示するかは、XAMLのDataTemplate側で指定していますから、コード側では、画像を表示するとか、名前を表示するといった指定はありません。DataContextにセットしているだけです。

using System;
using System.Windows;
using System.Windows.Media.Imaging;
namespace DataTemplateSample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }
        private void Window_Loaded(object sender, RoutedEventArgs e) {
            MyImage mi = new MyImage();
            mi.Name = @"コスモス";
            mi.Bitmap = new BitmapImage();
            mi.Bitmap.BeginInit();
            Uri uri = new Uri("Images/SampleImage.jpg", UriKind.Relative);
            mi.Bitmap.UriSource = uri;
            mi.Bitmap.EndInit();
            myImage.DataContext = mi;
        }
    }
}

実行結果です。

dataTemplate2

ちなみに、Windows_Loaded イベントハンドラを記述せずに、XAMLだけで書くとすると以下のように書けます。
このとき、C#で追加記述するのは、MyImage クラスだけとなります。

<Window x:Class="DataTemplateSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataTemplateSample"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:MyImage}">
            <StackPanel Name="stackPanel1" Orientation="Horizontal">
                <Image Height="80" Stretch="Uniform" Source="{Binding Bitmap}"/>
                <Label Content="{Binding Name}" FontSize="14" VerticalAlignment="Center"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Window.DataContext>
        <local:MyImage  Name="コスモス">
            <local:MyImage.Bitmap>
                <BitmapImage UriSource="Images/SampleImage.jpg" />
            </local:MyImage.Bitmap>
        </local:MyImage>
    </Window.DataContext>
    <Grid>
        <ContentControl Name="myImage" Content="{Binding Mode=OneWay}" Height="80" />
    </Grid>
</Window>


WPFサンプル・目次
  

Posted by gushwell at 23:10Comments(0)TrackBack(0)

2013年07月15日

WPFサンプル:DataTemplateでデータの表示形式を定義する

   このエントリーをはてなブックマークに追加 Clip to Evernote
DataTemplateを使うと、データの視覚的表現を定義することができます。
例えば、あるオブジェクトの表現を数値であらわすか、文字列であらわすか、それともグラフィックスで表すかは、視覚的表現の部分です。DataTemplateを使うことで、このどういった表現で表示するのかを指定できます。

DateTime型のオブジェクトの表示をカスタマイズするサンプルを書いてみました。

まずは、C#のコードから。

using System;
using System.Windows;
namespace DataTemplate1Sample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }
        private void Window_Loaded_1(object sender, RoutedEventArgs e) {
            label1.Content = DateTime.Now;
        }
    }
}

C#のコードでは、label1.DataContextに DateTime.Nowをセットしているだけです。
つまり、コードでは日付を表示することだけに集中し、どのように表示するかは、XAML側に任せてしまおうということです。

どのように表示するかは、以下に示すように XAMLのDataTemplateで指定します。

<Window x:Class="DataTemplate1Sample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" Height="150" Width="525" Loaded="Window_Loaded_1">
    <Window.Resources>
        <DataTemplate DataType="{x:Type system:DateTime}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Year}"></TextBlock>
                <TextBlock Text="年"></TextBlock>
                <TextBlock Text="{Binding Path=Month}"></TextBlock>
                <TextBlock Text="月"></TextBlock>
                <TextBlock Text="{Binding Path=Day}"></TextBlock>
                <TextBlock Text="日"></TextBlock>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Label Height="40" FontSize="20" Name="label1" Content="{Binding}"/>
    </Grid>
</Window>

Windows.Resources要素に記述した DataTemplateの定義では、DataTypeでDateTime型のDataTemplateであることを指定しています。XAMLにDateTime型を認識させるために、名前空間を利用しています。
そして、DataTemplateの子要素としてどのような表示にするのかを指定しています。ここでは、StackPanelのなかにTextBlockを複数配置し、TextプロパティとDateTimeのYear, Month, Dayプロパティとをバインドさせています。

実行結果を示します。

dataTemplate1

WPFサンプル・目次
  
Posted by gushwell at 22:00Comments(0)TrackBack(0)