「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
基本的なXAMLの書き方。
XAMLにおける各種の名前空間の宣言は、xmlns属性を使用したXML名前空間にて行う。
ここでは、以下の既定の名前空間の宣言を例にとって説明する。
<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
2行目のXML名前空間の宣言(xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation")では、
WPFフレームワーク(PresentationFramework?.dll)のアセンブリ内に同梱されるURIにマップされた
CLR名前空間(System.Windows.Controls、System.Windows.Dataなど)を、既定のXML名前空間(プレフィックスなし)として割り当てている。
そのため、既定でXAMLからWPFフレームワークのCLRオブジェクトを利用できる。
3行目のXML名前空間の宣言(xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml")では、
URIにマップされた共通的なXAMLの言語機能がXML名前空間(x)として割り当てられている。
これにより、「x:」というプレフィックスを使用することで、「言語機能」で説明する、XAMLの言語機能を使用できるようになる。
CLR名前空間について以下を例にとって説明する。
<Window x:Class="WpfApplication1.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:igDP="http://infragistics.com/DataPresenter" <--- 名前空間の宣言(追加
  Title="Window1" Height="300" Width="300">
  <Grid>
    <igDP:XamDataGrid Name="xamDataGrid1"/> <--- 名前空間の使用例
  </Grid>
</Window>Infragistics社製のNetAdvantage?など、
XmlnsDefinition?アセンブリ属性でURIとCLR名前空間のマップが指定された
サードパーティ製のUIコンポーネントをD&DでVSデザイナから追加した場合、
上記の例のように自動的にXML名前空間の宣言が追加される。
なお、XML名前空間には一意の名前を自由に付与でき(上記の例ではigDP)、
このプレフィックスを使用することで、XAMLからUIコンポーネントのCLRオブジェクトを利用できる。
この他に、URIとしてCLR名前空間とアセンブリを直接指定する方法もある。
xmlns:sys="clr-namespace:(CLR名前空間);assembly=(アセンブリ名)"
<Window x:Class="WpfApplication1.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:igDP="clr-namespace:Infragistics.Windows.DataPresenter;assembly=Infragistics3・・・" <--- 名前空間の宣言
  Title="Window1" Height="300" Width="300">
  <Grid>
    <igDP:XamDataGrid Name="xamDataGrid1"/> <--- 名前空間の使用例<Window x:Class="WpfApplication1.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib" <--- 名前空間の宣言
  Title="Window1" Height="300" Width="300">
  <Window.Resources>
    <x:Array x:Key="List" Type="{x:Type sys:String}"> <--- 名前空間の使用例<Window x:Class="WpfApplication1.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:uc="clr-namespace:WpfApplication1" <--- 名前空間の宣言
  Title="Window1" Height="300" Width="300">
  <StackPanel Orientation="Vertical">
    <uc:UserControl1 x:Name="userControl1"/> <--- 名前空間の使用例XAMLの言語機能である
について説明する。
XAMLの言語機能が提供する各種ディレクティブについて説明する。
| 項番 | ディレクティブ | 説明 | 
| 例 | ||
| 1 | x:Class | XAML上から分離クラス(コード ビハインド)のクラス名を定義する。 | 
| <Window x:Class="WpfApplication1.Window1" | ||
| 2 | x:Subclass | パーシャル クラスをサポートしない言語で使用する。通常は利用しない。 | 
| - | ||
| 3 | x: ClassModifier? | クラスのアクセスレベルを変更する。通常は利用しない。 | 
| - | ||
| 4 | x:Code | XAML上にインラインコードを実装する場合に使用する。通常は利用しない。 | 
| <Grid> <x:Code> <![CDATA[ void button1_Click(object sender, RoutedEventArgs? e) { button1.Content = "Hello World"; } ]]> </x:Code> <Button Name="button1" Click="button1_Click">Button</Button> </Grid>  | ||
| 5 | x:FieldModifier? | プロパティのアクセスレベルを変更する。通常は利用しない。 | 
| - | ||
| 6 | x:Key | XAMLで定義された各種「リソース」を識別する。下記は、x:Keyを使用して「スタイル」の「リソース」をボタンに「データ バインディング」する例。 | 
| <Window.Resources> <Style x:Key="buttonStyle" TargetType?="{x:Type Button}"> <Setter Property="Background" Value="LightYellow?" /> </Style> </Window.Resources> <Grid> <Button Style="{StaticResource? buttonStyle}">Hello Style</Button> </Grid>  | ||
| 7 | x:Name | XAMLで生成したCLRオブジェクトに名前を付与する。Name属性と差異は無い。 | 
| <Button x:Name="button1"> Click Here </Button>  | ||
| 8 | x:Shared | 静的なリソースを、取得の度に生成する場合に使用する。通常は利用しない。 ※ true : 静的(全てのインスタンスは同じ) false : 動的(取得の度に生成する) 既定値 : true  | 
| - | ||
| 9 | x:TypeArguments? | ジェネリックの型引数をコンストラクタに渡す。 (.NET Framework 4.0のXAML 2009からのサポート)  | 
| <!-- XAML 2009 --> <ObservableCollection? x:TypeArguments?="Employee"> <l:Employee FirstName?="John" Name="Doe" /> <l:Employee FirstName?="Tim" Name="Smith" /> </ObservableCollection?>  | ||
| 10 | x:Uid | ローカライゼーションのプロセスとツールによって使用される一意識別子を指定する 。 | 
| - | ||
| 11 | xml:lang | カルチャ情報を宣言する。 | 
| <Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xml:lang="ja-JP"  | 
XAMLの言語機能が提供する各種「マークアップ拡張」について説明する。
通常、「マークアップ拡張」は、「{」と「}」の2つの中括弧を使用することでXAMLパーサに対し、拡張されたプロパティ指定方法を指示する。
以下、XAMLの機能である「XAMLで定義されたマークアップ拡張」を一覧する。
これらの種類は、中括弧+「x:」プレフィックスの直後の文字列トークンによって識別される。
| 項番 | 文字列トークン | 説明 | 
| 例 | ||
| 1 | x:Static | 静的プロパティ(定数、静的プロパティ、フィールド、列挙値)を参照する。 構文:<object property="{x:Static Member=prefix:typeName.staticMemberName?}" .../>  | 
| <Button  Foreground="{x:Static Member=SystemColors?.InfoTextBrush?}" Background="{x:Static Member=SystemColors?.InfoBrush?}"> Click Here </Button>  | ||
| 2 | x:Null | CLRオブジェクトのプロパティにnull値を設定する(既定値をnullクリアする場合など)。 | 
| <Button x:Name="button1" Background="{x:Null}" Click="button1_Click"> Click Here </Button>  | ||
| 3 | x:Type | CLRクラスの型情報を指定する。 | 
| 詳しくは、下記、項番4の例を参照のこと。 | ||
| 4 | x:Array | IEnumerableを持つArrayオブジェクト(配列)を生成する。 | 
| <Window.Resources> <x:Array x:Key="List" Type="{x:Type sys:String}"> <sys:String>A</sys:String> <sys:String>B</sys:String> <sys:String>C</sys:String> </x:Array> </Window.Resources> <StackPanel?> <ListBox? ItemsSource?="{Binding Source={StaticResource? List}}"/> </StackPanel?> ※ 先頭で、.NET FrameworkのSystem名前空間のインポートが必要 xmlns:sys="clr-namespace:System;assembly=mscorlib" ※ StaticResource?については次項で説明する。  | 
※ x:Arrayは、例外的に中括弧と共に使用しない。
以下、WPF の機能である「WPF固有のマークアップ拡張」を一覧する。
こちらは、プロパティ値に「データ バインディング」や、「リソース」への参照を指定できる。
| 項番 | 文字列トークン | 説明 | 
| 構文 ※ 「プロパティ属性構文」と「プロパティ要素構文」については、後述する。 | ||
| 1 | {Binding ・・・  | Bindingオブジェクトに「バインディング ターゲット」のプロパティを設定することで、「データ バインディング」を実装する。 MSDN > WPFの基礎 > WPFのXAML > WPF XAML拡張機能 > バインディングのマークアップ拡張機能 http://msdn.microsoft.com/ja-jp/library/ms750413.aspx  | 
| 具体例は、「データ バインディングの基礎」を参照のこと。 | ||
| 2 | {StaticResource? ・・・  | 既に定義されたリソースに対する参照を検索し、任意のXAMLプロパティ属性の値を設定する。 | 
| 具体例は、「リソースとのデータ バインディング」を参照のこと。 プロパティ属性構文: <object property="{StaticResource? key}" .../> なお、「データ バインディング」で使用する場合は、次のようになる。 <object property="{Binding Source={StaticResource? key} ...}" .../> プロパティ要素構文: <object> <object.property> <StaticResource? ResourceKey?="key" .../> </object.property> </object>  | ||
| 3 | {DynamicResource? ・・・  | リソースが変化したときに、任意のXAMLプロパティ属性の値を設定する。 keyには、x:Key属性によって指定された既存の「リソース」に対応するキーを指定する。  | 
| 具体例は、「リソースとのデータ バインディング」を参照のこと。 プロパティ属性構文: <object property="{DynamicResource? key}" .../> なお、「データ バインディング」で使用する場合は、次のようになる。 <object property="{Binding Source={DynamicResource? key} ...} " .../> プロパティ要素構文: <object> <object.property> <DynamicResource? ResourceKey?="key" .../> </object.property> </object>  | ||
| 4 | {TemplateBinding? ・・・  | 親コントロールに適用したプロパティ値を「テンプレート」に反映させる。 MSDN > WPFの基礎 > WPFのXAML > WPF XAML拡張機能 > TemplateBinding?のマークアップ拡張機能 http://msdn.microsoft.com/ja-jp/library/ms742882.aspx  | 
| 具体例は、「テンプレート」を参照のこと。 プロパティ属性構文: <object property="{TemplateBinding? TargetProperty? }" .../>  | ||
| 5 | {RelativeSource? ・・・  | Binding.RelativeSource?を指定する。詳しくは、下記のURLを参照のこと。 また、次で例を挙げて説明する。 MSDN > WPFの基礎 > WPFのXAML > WPF XAML拡張機能 > RelativeSource?のマークアップ拡張機能 http://msdn.microsoft.com/ja-jp/library/ms743599.aspx  | 
| 具体例は、次を参照のこと。 プロパティ属性構文: <Binding RelativeSource?="{RelativeSource? modeEnumValue?}" .../> なお、「データ バインディング」で使用する場合は、次のようになる。 <object property="{Binding RelativeSource?={RelativeSource? modeEnumValue?} ...}" .../> プロパティ要素構文: <Binding> <Binding.RelativeSource?> <RelativeSource? Mode="modeEnumValue?"/> </Binding.RelativeSource?> </Binding> OR <Binding> <Binding.RelativeSource?> <Relative Mode="FindAncestor?" AncestorType?="{x:Type typeName}" AncestorLevel?="intLevel"/> </Binding.RelativeSource?> </Binding>  | ||
| 6 | {ThemeDictionary? ・・・  | カスタム コントロールの作成者やサードパーティ製のUIコンポーネントの、 コントロールの「スタイル」をアプリケーションの「リソース」から読み込む。 MSDN > WPFの基礎 > WPFのXAML > WPF XAML拡張機能 > ThemeDictionary?のマークアップ拡張機能 http://msdn.microsoft.com/ja-jp/library/ms752067.aspx  | 
| - | 
※ keyには、x:Keyディレクティブによって指定された既存のリソースに対応するキーを指定する。
プロパティの設定方法として、
の2つの構文について説明する。
以下、TextBox?要素に対して、同等の属性を設定する
「プロパティ属性構文」と「プロパティ要素構文」の例を示す。
要素の属性にテキストを使用してプロパティを設定する方法
<TextBox Width = "100" FontSize = "30" Text = "text1" Background = "White" Foreground = "Blue" />
要素のinnerText・innerXMLを使用してプロパティを設定する方法
<TextBox>
  <TextBox.Width>100</TextBox.Width>
  <TextBox.FontSize>30</TextBox.FontSize>
  <TextBox.Background>
    <SolidColorBrush Color="White"/>
  </TextBox.Background>
  <TextBox.Foreground>
    <SolidColorBrush Color="Blue"/>
  </TextBox.Foreground>
  <TextBox.Text>text1</TextBox.Text>
</TextBox>なお、子要素のコレクションを設定する「プロパティ要素構文」である
などは、暗黙的に使用されるため明記が不要のものもある。
XAMLパーサは、XAMLの「プロパティ属性構文」として指定された各属性テキストを、
プリミティブ型に変換できるリテラル文字列として解釈するか、「型コンバータ」を使用してオブジェクトに変換する。
なお、「型コンバータ」(と、そのベース クラスであるTypeConverter?クラス)は、
.NETのコンポーネントとコントロールのデザイン時・実行時の動作を実装する一般的なクラスであり、WPF独自のクラスではない。
しかし、XAMLの「プロパティ属性構文」からのCLRプロパティ設定を多用するWPF / Silverlight開発では、その存在を認識しておいたほうが良い。
XAMLパーサは通常、プロパティの型(CLRクラス)にTypeConverterAttribute?属性 が付与されているかを調べる。
付与されている場合は、この属性値に基づいた「型コンバータ」を使って、TypeConverter?.ConvertFrom?メソッド により文字列をプロパティ値に変換する。
以下は、ユーザ コントロールに、MyPoint?というカスタムの型を取るCLRプロパティを実装しXAMLに公開、
XAMLの「プロパティ属性構文」として指定された各属性テキストを、カスタムの型に変換する「型コンバータ」を実装した例である。
MyPoint?というカスタム型(型コンバータを実装)
/// <summary>
/// カスタム型(型コンバータを実装)
/// </summary>
[TypeConverter(typeof(MyPointConverter))]
public class MyPoint {
  public MyPoint(int x, int y) {
    this._x = x;
    this._y = y;
  }
  private int _x;
  public int X {
    set { this._x =value; }
    get { return this._x; } 
  }
  private int _y;
  public int Y {
    set { this._y = value; }
    get { return this._y; }
  }
}
/// <summary>カスタム型の型コンバータ</summary>
public class MyPointConverter : TypeConverter {
  /// <summary>CanConvertFrom(変換可能かチェックする)</summary>
  public override bool CanConvertFrom(
    ITypeDescriptorContext context, Type sourceType) {
    if (sourceType == typeof(string)) {
      return true;
    }
    return base.CanConvertFrom(context, sourceType);
  }
  /// <summary>指定された文字列をカスタム型(MyPoint)に変換する</summary>
  public override object ConvertFrom(
    ITypeDescriptorContext context,
    CultureInfo culture, object value) {
    if (value is string) {
      string[] v = ((string)value).Split(new char[] { ',' });
      return new MyPoint(int.Parse(v[0]), int.Parse(v[1]));
    }
    return base.ConvertFrom(context, culture, value);
  }
  /// <summary>指定されたカスタム型(MyPoint)を文字列に変換する</summary>
  public override object ConvertTo(ITypeDescriptorContext context,
    CultureInfo culture, object value, Type destinationType) {
    if (destinationType == typeof(string)) {
      return ((MyPoint)value).X + "," + ((MyPoint)value).Y;
    }
    return base.ConvertTo(context, culture, value, destinationType);
  }
}
MyPoint?というカスタム型のCLRプロパティを実装
/// <summary>
/// UserControl1.xaml の相互作用ロジック
/// </summary>
public partial class UserControl1
  : UserControl {
  // CLRプロパティの定義(XAML属性に公開可能)
  private MyPoint _myLocation;
  public MyPoint MyLocation {
    set { this._myLocation = value; }
    get { return this._myLocation; }
  }
・・・
上記のユーザ コントロールのカスタムの型を取るCLRプロパティを、以下のようにXAMLの「プロパティ属性構文」として指定された各属性テキストから初期化できる。
<uc:UserControl1 x:Name="userControl1" MyLocation="10,20"/>
ただし、(当然ながら、)文字列からの変換をサポートしているだけで、すべてのプロパティ値をサポートすることはできない。
文字列で表現できないプロパティ値は、「プロパティ属性構文」ではなく「プロパティ要素構文」として記述する方法を取る。
「コンテンツ構文」とは、Contentプロパティ(またはItemsプロパティ)に要素を設定する構文である。
WPFのContentControl?は、
WPFのContentControl?のButtonコントロールを例にしてContentプロパティへ要素を設定する例を示す。
Contentプロパティには、Imageオブジェクトなどの任意の型の要素も設定できる。
<Button Width="200" Height="200">
  <Button.Content>
    <Image Source=".\Blue hills.jpg"/>
  </Button.Content>
</Button><Button Width="200" Height="200">
  <Button.Content>
    <StackPanel Orientation="Vertical">
      <Image Source=".\Blue hills.jpg" Margin="5" />
      <TextBlock Text="ボタン" HorizontalAlignment="Center" Margin="5"/>
    </StackPanel>
  </Button.Content>
</Button><Button Width="200" Height="200">
  <StackPanel Orientation="Vertical">
    <Image Source=".\Blue hills.jpg" Margin="5" />
    <TextBlock Text="ボタン" HorizontalAlignment="Center" Margin="5"/>
  </StackPanel>
</Button>WPFのItemsControl?は、Itemsプロパティに任意の型の子要素を設定することができるため、コントロールの「外観」を自由に変更できる。
ItemsControl?のItemsプロパティへは、複数のコンテンツを追加できる。
以下、ListBox?コントロールを例にしてItemsプロパティへ子要素の設定する例を示す。
<Grid>
  <ListBox>
    <Border BorderBrush ="Black" BorderThickness ="1" Margin="5">
      <StackPanel Orientation="Horizontal" Height="120" Width="250" Margin="5">
        <Image Source=".\Blue hills.jpg" Height="100"/>
        <TextBlock Text="Blue hills" VerticalAlignment="Center"/>
      </StackPanel>
    </Border>
    <Border BorderBrush ="Black" BorderThickness ="1" Margin="5">
      <StackPanel Orientation="Horizontal" Height="120" Width="250" Margin="5">
        <Image Source=".\Sunset.jpg" Height="100"/>
        <TextBlock Text="Sunset" VerticalAlignment="Center"/>
      </StackPanel>
    </Border>
    <Border BorderBrush ="Black" BorderThickness ="1" Margin="5">
      <StackPanel Orientation="Horizontal" Height="120" Width="250" Margin="5">
        <Image Source=".\Water lilies.jpg" Height="100"/>
        <TextBlock Text="Water lilies" VerticalAlignment="Center"/>
      </StackPanel>
    </Border>
    <Border BorderBrush ="Black" BorderThickness ="1" Margin="5">
      <StackPanel Orientation="Horizontal" Height="120" Width="250" Margin="5">
        <Image Source=".\Winter.jpg" Height="100"/>
        <TextBlock Text="Winter" VerticalAlignment="Center"/>
      </StackPanel>
    </Border>
  </ListBox>
</Grid>ここでは、
について説明する。
※「リソース」の「データ バインディング」については、
「リソースとのデータ バインディングを参照のこと。
「リソース」とは、ResourceDictionary? 型のオブジェクトであり、
に「プロパティ要素構文」を使用して定義できる。
このため、任意のUI要素に定義可能であるが、
通常はルート要素(Window or Page)上に定義する。
また、「リソース」は、定義場所により以下のような呼称・特徴がある。
<Window.Resources>
  <x:Array x:Key="List" Type="{x:Type sys:String}">
    <sys:String>A</sys:String>
    <sys:String>B</sys:String>
    <sys:String>C</sys:String>
  </x:Array>
</Window.Resources>
※ 先頭で、String型のインポートが必要
xmlns:sys="clr-namespace:System;assembly=mscorlib"
「リソース」を定義したら、各種「マークアップ拡張」を使用して、
プロパティ値に「データ バインディング」や、「リソース」への参照を指定できる。
この時、参照する側からx:Key ディレクティブを使用して割り当てたキーを「リソース」検索のキーとして指定できる。
なお、「スタイル」や「テンプレート」などは、キーを定義せず、TargetType? 属性のみ使用して、
指定の型のオブジェクトに「スタイル」や「テンプレート」を適用することもできる。
これについては、「スタイルとテンプレート」を参照のこと。
以下、「リソース」の定義と、プロパティ値に「リソース」への参照を指定する例を示す。
StaticResource?参照では、
以下は、StaticResource?の定義と参照例。
<Window.Resources>
  <SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
</Window.Resources>
<Grid>
  <Ellipse Fill="{StaticResource ResourceKey=BlueBrush}" Height="150" Width="150"/>
</Grid>
↓ 「ResourceKey? =」という記述を省略
<Window.Resources>
  <SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
</Window.Resources>
<Grid>
  <Ellipse Fill="{StaticResource BlueBrush}" Height="150" Width="150"/>
</Grid>
<Window.Resources>
  <SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
</Window.Resources>
<Grid>
  <Ellipse Height="150" Width="150">
    <Ellipse.Fill>
      <StaticResource ResourceKey="BlueBrush"/> 
    </Ellipse.Fill>
  </Ellipse>
</Grid>以下は、DynamicResource?の定義と参照例。
<Grid>
  <Grid.RowDefinitions>
    <RowDefinition/>
    <RowDefinition/>
  </Grid.RowDefinitions>
  <Ellipse Grid.Row="0"
    Fill="{StaticResource ResourceKey={x:Static SystemColors.HighlightBrushKey}}"/>
  <Ellipse Grid.Row="1"
    Fill="{DynamicResource ResourceKey={x:Static SystemColors.HighlightBrushKey}}"/>
</Grid>
<Window.Resources>
  <SolidColorBrush x:Key="MyBrush" Color="Blue"/>
</Window.Resources>
<Grid>
  <Grid.RowDefinitions>
    <RowDefinition/>
    <RowDefinition/>
    <RowDefinition Height="23"/>
  </Grid.RowDefinitions>
  <Ellipse Grid.Row="0" Fill="{StaticResource MyBrush}"/>
  <Ellipse Grid.Row="1" Fill="{DynamicResource MyBrush}"/>
  <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center">
    <Button Content="青" Height="23" Name="button1" Width="75" Click="button1_Click" />
    <Button Content="赤" Height="23" Name="button2" Width="75" Click="button2_Click" />
  </StackPanel>
</Grid>private void button1_Click(object sender, RoutedEventArgs e) {
  this.Resources["MyBrush"] = Brushes.Blue;
}
private void button2_Click(object sender, RoutedEventArgs e) {
  this.Resources["MyBrush"] = Brushes.Red;
}ResourceDictionary?は、「ディクショナリ ファイル」に定義することもできる。
「ディクショナリ ファイル」を追加する際は、
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <SolidColorBrush x:Key="BlueBrush" Color="Blue"/> </ResourceDictionary>ディクショナリ ファイルの定義例 (Dictionary1.xaml)
<Window.Resources>
  <ResourceDictionary Source="Dictionary1.xaml"/>
</Window.Resources>
<Grid>
  <Ellipse Fill="{StaticResource BlueBrush}" Height="150" Width="150"/>
</Grid>StaticResource?参照 + ディクショナリ ファイルの使用例
以下の、その例を示す。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <SolidColorBrush x:Key="MyBrush" Color="Blue"/> </ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <SolidColorBrush x:Key="MyBrush" Color="Red"/> </ResourceDictionary>
<StackPanel>
  <Ellipse Fill="{DynamicResource MyBrush}" Height="150" Width="150"/>
  <Button Content="青" Height="23" Name="button1" Width="75" Click="button1_Click" />
  <Button Content="赤" Height="23" Name="button2" Width="75" Click="button2_Click" />
</StackPanel>public partial class Window1 : Window {
  public Window1() {
    InitializeComponent();
    this.LoadResourceDictionary("Dictionary1.xaml");
  }
  private void button1_Click(object sender, RoutedEventArgs e) {
    this.LoadResourceDictionary("Dictionary1.xaml");
  }
  private void button2_Click(object sender, RoutedEventArgs e) {
    this.LoadResourceDictionary("Dictionary2.xaml");
  }
  private void LoadResourceDictionary(string name) {
    ResourceDictionary dictionary =
      (ResourceDictionary)Application.LoadComponent(new Uri(name, UriKind.Relative));
    if (dictionary != null) Application.Current.Resources = dictionary;
  }
}DynamicResource?参照 + ディクショナリ ファイルの使用例
様々なソースと「データ バインディング」するサンプルを示す。
なお、サンプルのXAMLソースを読むためには、以下の、
Bindingプロパティの設定方法を理解しておく必要がある。
Bindingプロパティの設定方法
| 項番 | プロパティ | 説明 | 
| 1 | Mode | OneTime?、OneWay?、TwoWay? のいずれかの「バインディング モード」を指定する。 | 
| 2 | Source | 「バインディング ソース」を指定する。「バインディング ソース」は、 「リソース」に定義し、StaticResourceの「マークアップ拡張」を使用して「データ バインディング」するか、 FrameworkElement?.DataContext?から、「データ バインディング」する。  | 
| 3 | ElementName? | UI要素名を使用して「バインディング ソース」を指定する。 | 
| 4 | RelativeSource | 「バインディング ターゲット」からの相対位置で「バインディング ソース」を指定する。 ※ Self、TemplatedParent?、AncestorType?、AncestorLevel?属性などを使用して指定する。  | 
| 5 | Path | 「バインディング ソース」のプロパティ名を指定する(名前空間のフルパスで指定可)。 なお、インデクサなどの指定も可能である。詳細は、以下のURLを参照のこと。  | 
| 6 | XPath | 「バインディング ソース」として、XMLデータソースのXML DOMへのパスを表す文字列を指定する。 | 
| 7 | TargetNullValue? | ソース値が null のときに返される値を指定する。 | 
| 8 | Converter | 「値コンバータ」を指定する。 「値コンバータ」は、インスタンス化が可能であり、ResourceDictionary?に配置できる。 「値コンバータ」は「StaticResource?」に定義しStaticResourceの「マークアップ拡張」を使用して参照するようにする。  | 
| 9 | ConverterCulture? | 「値コンバータ」で使用するカルチャを指定する。 | 
| 10 | ConverterParameter? | 「値コンバータ」の変換ロジックで使用するパラメタを指定する。 | 
以下、「WPFのアーキテクチャ - データ バインディング」に対応するサンプルを示す。
<StackPanel x:Name="MainPanel" Loaded="MainPanel_Loaded"> <TextBlock x:Name="TextBlock1"/> <TextBlock x:Name="TextBlock2"/> </StackPanel>
public partial class Window1 : Window {
  public Window1() {
    InitializeComponent();
  }
  private void MainPanel_Loaded(object sender, RoutedEventArgs e)
  {
    // バインディング ソース(Person)
    Person BindingSource =
      new Person() { Height = 1.7, Weight = 60 };
    // Bindingオブジェクトによりバインド
    // HeightプロパティをOneWayでバインド
    Binding BindingHeight = new Binding("Height");
    BindingHeight.Mode = BindingMode.OneWay;
    // バインディング ソース(Person)
    BindingHeight.Source = BindingSource;
    // バインディング ターゲット(TextBlock)
    TextBlock1.SetBinding(TextBlock.TextProperty, BindingHeight);
    // WeightプロパティをOneWayでバインド
    Binding BindingWeight = new Binding("Weight");
    BindingWeight.Mode = BindingMode.OneWay;
    // バインディング ソース(Person)
    BindingWeight.Source = BindingSource;
    // バインディング ターゲット(TextBlock)
    TextBlock2.SetBinding(TextBlock.TextProperty, BindingWeight);
  } 
}
/// <summary>バインディング ソース(Person)</summary>
public class Person {
  public double Height { get; set; }
  public double Weight { get; set; }
}上記のMainPanel_Loadedメソッドのコードを一部編集し、MainPanel?(StackPanel?)の
FrameworkElement?.DataContext?プロパティに「バインディング ソース」を設定することで、
Bindingオブジェクトへの「バインディング ソース」の指定が不要になる。
private void MainPanel_Loaded(object sender, RoutedEventArgs e) {
  // バインディング ソース(Person)
  MainPanel.DataContext =
    new Person() { Height = 1.7, Weight = 60 };
  // Bindingオブジェクトによりバインド
  // HeightプロパティをOneWayでバインド
  Binding BindingHeight = new Binding("Height");
  BindingHeight.Mode = BindingMode.OneWay;
  // バインディング ターゲット(TextBlock)
  this.TextBlock1.SetBinding(TextBlock.TextProperty, BindingHeight);
  // WeightプロパティをOneWayでバインド
  Binding BindingWeight = new Binding("Weight");
  BindingWeight.Mode = BindingMode.OneWay;
  // バインディング ターゲット(TextBlock)
  TextBlock2.SetBinding(TextBlock.TextProperty, BindingWeight);
}<StackPanel 
  x:Name="MainPanel"
  Loaded="MainPanel_Loaded">
  <TextBlock>
    <TextBlock.Text>
      <Binding Path="Height" Mode="OneWay"/>
    </TextBlock.Text>
  </TextBlock>
  <TextBlock>
    <TextBlock.Text>
      <Binding Path="Weight" Mode="OneWay"/>
    </TextBlock.Text>
  </TextBlock>
</StackPanel>private void MainPanel_Loaded
   (object sender, RoutedEventArgs e) {
  // バインディング ソース(Person)
  MainPanel.DataContext =
  new Person() { Height = 1.7, Weight = 60 };
}<StackPanel x:Name="MainPanel" Loaded="MainPanel_Loaded">
  <TextBlock Text="{Binding Path=Height, Mode=OneWay}" />
  <TextBlock Text="{Binding Path=Weight, Mode=OneWay}" />
</StackPanel><StackPanel x:Name="MainPanel" Loaded="MainPanel_Loaded">
  <TextBlock Text="{Binding Height, Mode=OneWay}" />
  <TextBlock Text="{Binding Weight, Mode=OneWay}" />
</StackPanel>下記は、モード:OneWay? or OneWayToSource?を併用した「データ バインディング」によるBMI(肥満度)の自動計算アプリケーションの例である。
この例では、「バインディング ソース」のプロパティ値の変更を、自動的に「バインディング ターゲット」に反映できる。
なお、この際、「バインディング ソース」は、INotifyPropertyChanged?インターフェイスを実装して、BMI(肥満度)プロパティの変更通知処理を実装する必要がある。
<StackPanel x:Name="MainPanel" Loaded="MainPanel_Loaded">
  <TextBox Margin="10" Text="{Binding Height, Mode=OneWayToSource}"/>
  <TextBox Margin="10" Text="{Binding Weight, Mode=OneWayToSource}"/>
  <Button Margin="10" Content="計算" Click="Button_Click" />
  <TextBlock Margin="10" Text="{Binding Bmi, Mode=OneWay}"/>
</StackPanel>/// <summary>/// Window1.xaml の相互作用ロジック/// </summary>
public partial class Window1 : Window {
  public Window1() {
    InitializeComponent();
  }
  /// <summary>初期化イベント</summary>
  private void MainPanel_Loaded(object sender, RoutedEventArgs e) {
    // バインド ソース(Person)
    MainPanel.DataContext = new Person();
  }
  /// <summary>計算イベント</summary>
  private void Button_Click(object sender, RoutedEventArgs e) {
    ((Person)MainPanel.DataContext).Calculate();
  } 
}/// <summary>バインド ソース(Person)</summary>
public class Person : INotifyPropertyChanged {
  public double Height { get; set; }
  public double Weight { get; set; }
  double _bmi;
  public double Bmi {
    get { return this._bmi; }
    set {
      this._bmi = value;
      // 変更通知
      this.OnPropertyChanged("Bmi");
    }
  }
  /// <summary>計算処理</summary>
  public void Calculate() {
    this.Bmi = Weight / Math.Pow(Height, 2);
  }
  #region INotifyPropertyChanged メンバ
  /// <summary>値変更イベントの定義</summary>
  public event PropertyChangedEventHandler PropertyChanged;
  /// <summary>変更通知(値変更イベントを発生させる)</summary>
  protected virtual void OnPropertyChanged(string propertyName) {
    PropertyChangedEventHandler handler = this.PropertyChanged;
    if (handler != null)
      handler(this, new PropertyChangedEventArgs(propertyName));
  }
  #endregion
}続いて、上記処理に、BMI(肥満度)プロパティが
変更する処理を追加する。
これには別途、背景色プロパティを定義することで実現することも可能であるが、
ここでは、前述のIValueConverter?インターフェイスを実装した「値コンバータ」を実装することでこれを実現する。
値の変換処理は、「値コンバータ」のConvertメソッドに実装する。
<Window.Resources>
  <my:BmiLevelConverter x:Key="bmiLevelConverter"/>
</Window.Resources>
<StackPanel x:Name="MainPanel" Loaded="MainPanel_Loaded">
  <TextBox Margin="10" Text="{Binding Height, Mode=OneWayToSource}"/>
  <TextBox Margin="10" Text="{Binding Weight, Mode=OneWayToSource}"/>
  <Button Margin="10" Content="計算" Click="Button_Click" />
  <TextBlock Margin="10"
    Text="{Binding Bmi, Mode=OneWay}"
    Background="{Binding Bmi, Mode=OneWay,
    Converter={StaticResource bmiLevelConverter}}"/>
</StackPanel>/// <summary>BMIレベルに合った背景色を返す</summary>
public class BmiLevelConverter : IValueConverter {
  #region IValueConverter メンバ
  /// <summary>変換メソッド(ソースからターゲット)</summary>
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
    // BMIレベルに合った背景色を返す
    double target = (double)value;
    SolidColorBrush level;
    if (target < 18.5)
      level = new SolidColorBrush(Colors.Blue);
    else if (target > 25)
      level = new SolidColorBrush(Colors.Red);
    else
      level = new SolidColorBrush(Colors.White);
    return level;
  }
  /// <summary>変換メソッド(ターゲットからソース)</summary>
  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
    throw new NotImplementedException();
  }
  #endregion
}なお、変更通知は、INotifyPropertyChanged?インターフェイスの実装ではなく、「依存関係プロパティ」でも代替できる。
上記の例のBMI(肥満度)プロパティを「依存関係プロパティ」として、以下のように書き直し、動作を確認する。
/// <summary>バインド ソース(Person)</summary>
public class Person : DependencyObject {
  public double Height { get; set; }
  public double Weight { get; set; }
  /// <summary>Bmiプロパティを依存関係プロパティとして登録</summary>
  public static readonly DependencyProperty BmiProperty =
    DependencyProperty.Register("Bmi", typeof(double), typeof(Person), 
        new UIPropertyMetadata(0.0));
  /// <summary>BmiプロパティのCLRプロパティ</summary>
  public double Bmi {
    get { return (double)this.GetValue(Person.BmiProperty); }
    set { this.SetValue(Person.BmiProperty, value); }
  }
  /// <summary>計算処理</summary>
  public void Calculate(){
    this.Bmi = Weight / Math.Pow(Height, 2);
  }
}BMI(肥満度)プロパティが変更されると、UI要素(TextBlock?)に変更が反映されることを確認できる。
このように、「依存関係プロパティ」は既定で変更通知をサポートしている。
以下の例では、モード:TwoWay?の「データ バインディング」を行うため、
2つのUI要素、TextBox?とSliderを双方向接続した例である。
なお前述のようにUI要素の表示に関するプロパティは、
基本的に「依存関係プロパティ」として定義されており、
既定で変更通知をサポートしている。このため、既定で双方向接続が可能である。
なお、「バインディング ソース」をUI要素に接続する場合は、ElementName?属性を使用すると良い。
<StackPanel Orientation="Vertical">
  <Label>TextBox</Label>
  <TextBox x:Name="textBox1" Text="5"/>
  <Rectangle Height="20"></Rectangle>
  <Label>Slider</Label>
  <Slider x:Name="Slider1" 
    Value="{Binding ElementName=textBox1, Path=Text, Mode=TwoWay}"/>
</StackPanel><StackPanel Orientation="Vertical">
  <Label>TextBox</Label>
  <TextBox x:Name="textBox1"
    Text="{Binding ElementName=Slider1, Path=Value, Mode=TwoWay}"/>
  <Rectangle Height="20"></Rectangle>
  <Label>Slider</Label>
  <Slider x:Name="Slider1" Value="5"/>
</StackPanel>双方向の値の変換に対応した「値コンバータ」は、
Convert、ConvertBack?メソッドの双方を実装する必要がある。
<Window.Resources>
  <my:ValConverter x:Key="valConverter" />
</Window.Resources>
<StackPanel Orientation="Vertical">
  <Label>TextBox</Label>
  <TextBox x:Name="textBox1" Text="500"/>
  <Rectangle Height="20"></Rectangle>
  <Label>Slider</Label>
  <Slider x:Name="Slider1"
    Value="{Binding ElementName=textBox1, Path=Text, Mode=TwoWay,
    Converter={StaticResource valConverter}}"/>
</StackPanel>public class ValConverter : IValueConverter {
  #region IValueConverter メンバ
  /// <summary>変換メソッド(ソースからターゲット)</summary>
  public object Convert(object value, Type targetType,
    object parameter, System.Globalization.CultureInfo culture) {
    return int.Parse(value.ToString()) / 100;
  }
  /// <summary>変換メソッド(ターゲットからソース)</summary>
  public object ConvertBack(object value, Type targetType,
    object parameter, System.Globalization.CultureInfo culture) {
    return ((double)value) * 100;
  }
  #endregion
}ItemsControl?から派生した要素のItemsSource?属性にコレクションを「データ バインディング」する場合、対象オブジェクトは反復処理をサポートしている必要がある。
<StackPanel x:Name="stackPanel1">
  <ListBox x:Name="listBox1" ItemsSource="{Binding}"/>
  <Button Height="23" Name="button1" Click="button1_Click">Button</Button>
</StackPanel>public partial class Window1 : Window {
  ObservableCollection<string> _cities = new ObservableCollection<string>();
  public Window1() {
    InitializeComponent();
    this._cities.Add("札幌市");
    this._cities.Add("仙台市");
    this._cities.Add("静岡市");
    this.stackPanel1.DataContext = _cities;
  }
  private void button1_Click(object sender, RoutedEventArgs e) {
    this._cities.Add("神戸市" + this.listBox1.Items.Count.ToString());
  }
}<StackPanel x:Name="stackPanel1">
  <ListBox ItemsSource="{Binding}"/>
</StackPanel>public Window1() {
  InitializeComponent();
  // バンディング ソース(コレクション)
  ObservableCollection<Border> cities = new ObservableCollection<Border>();
  // ワーク
  Border tmpBorder = null;
  StackPanel tmpStackPanel = null;
  Image tmpImage = null;
  TextBlock tmpTextBlock = null;
  // Borderの構築
  tmpBorder = new Border();
  tmpBorder.BorderBrush = Brushes.Black;
  tmpBorder.BorderThickness = new Thickness(1);
  tmpBorder.Margin = new Thickness(5);
  // StackPanelの構築
  tmpStackPanel = new StackPanel();
  tmpStackPanel.Orientation = Orientation.Horizontal;
  tmpStackPanel.Height = 120;
  tmpStackPanel.Width = 250;
  tmpStackPanel.Margin = new Thickness(5);
  // Imageの構築
  tmpImage = new Image();
  tmpImage.Source=new BitmapImage(
    new Uri(@".\Water lilies.jpg", UriKind.Relative));
  tmpImage.Height=100;
  // TextBlockの構築
  tmpTextBlock = new TextBlock();
  tmpTextBlock.Text="Water lilies";
  tmpTextBlock.VerticalAlignment = VerticalAlignment.Center;
  // 階層構造の組み立て
  tmpStackPanel.Children.Add(tmpImage);
  tmpStackPanel.Children.Add(tmpTextBlock);
  tmpBorder.Child = tmpStackPanel;
  // バンディング ソース(コレクション)に追加
  cities.Add(tmpBorder);
  // ・・・(n項繰り返し)・・・
  // データ バンディング
  stackPanel1.DataContext = cities;
}インデクサについても、Path属性に角括弧を指定することで接続可能である。
<Grid>
  <Image x:Name="Image1"
    Height="200" Width="200"
    Source="{Binding Path=[Source]}"
    ToolTip="{Binding Path=[ToolTip]}"/>
</Grid>public Window1() {
  InitializeComponent();
  Hashtable ht = new Hashtable();
  ht["Source"] = @".\Winter.jpg";
  ht["ToolTip"] = "Winter";
  this.Image1.DataContext = ht;
}これらを応用すると、
インデクサを持つオブジェクトの配列(反復処理をサポート)
をデータ バインディングすることも可能であることが分かる。
ビジネス・アプリケーションでは、DataGrid?へDataTable?をデータ バインディングする際に、
DataGrid?の列へDataTable?の列をマッピングするようなケースでよく利用します。
「リソース」参照を「バインディングのマークアップ拡張」でも使用することができる。
<Window.Resources>
  <sys:String x:Key="val">Click Here</sys:String >
</Window.Resources>
<StackPanel>
  <Button Content="{Binding Source={StaticResource val}}"/>
</StackPanel>
※ 先頭で、String型のインポートが必要
xmlns:sys="clr-namespace:System;assembly=mscorlib"
<Window.Resources>
  <x:Array x:Key="list"
    Type="{x:Type sys:String}">
    <sys:String>A</sys:String>
    <sys:String>B</sys:String>
    <sys:String>C</sys:String>
  </x:Array>
</Window.Resources>
<StackPanel>
  <ListBox ItemsSource="{Binding Source={StaticResource list}}"/>
</StackPanel>
※ 先頭で、String型のインポートが必要
xmlns:sys="clr-namespace:System;assembly=mscorlib"
動的な「リソース」を使用した「データ バインディング」はサポートされない。
以下、「{Binding Source={DynamicResource?」をテストした際のエラーメッセージである。
型 'Binding' の 'Source' プロパティで 'DynamicResourceExtension' を設定することはできません。'DynamicResourceExtension' は、DependencyObject の DependencyProperty でのみ設定できます。
ココでは、レイアウト方法として、
の2つについて説明する。
<Border Background="LightBlue" BorderBrush="Black" BorderThickness="2" Padding="15">
  <StackPanel Background="White" HorizontalAlignment="Center" VerticalAlignment="Top">
    <TextBlock Margin="5,0,5,0" HorizontalAlignment="Center">Alignment, Margin and Padding Sample</TextBlock>
    <Button HorizontalAlignment="Left" Margin="20">Button 1</Button>
    <Button HorizontalAlignment="Right" Margin="10">Button 2</Button>
    <Button HorizontalAlignment="Stretch" Margin="0">Button 3</Button>
  </StackPanel>
</Border>WPFでは、パネルを使用した「レイアウト」が可能である。
UIElement子要素の順序付けられたコレクションを表す。
XAMLから「プロパティ要素構文」の「コンテンツ構文」でパネル要素に子要素を追加する場合は、
<Panel.Children>タグを使用する(ただし、このタグを明示しなくとも、暗黙的に使用される)。
また、コード ビハインドから、パネル要素に子要素を追加する場合は、Children.Add メソッドを使用する。
<Canvas Background="LightSteelBlue">
  <TextBlock Canvas.Top="10" Canvas.Left="20">
    Hello World!
  </TextBlock>
  <TextBlock Canvas.Top="40" Canvas.Left="50">
    絶対位置決め方式は便利ではありませんか?
  </TextBlock>
</Canvas><DockPanel LastChildFill="True">
  <Border Height="25" Background="SkyBlue" DockPanel.Dock="Top">
    <TextBlock Foreground="Black">Dock = "Top(1)"</TextBlock>
  </Border>
  <Border Height="25" Background="SkyBlue" DockPanel.Dock="Top">
    <TextBlock Foreground="Black">Dock = "Top(2)"</TextBlock>
  </Border>
  <Border Height="25" Background="LemonChiffon" DockPanel.Dock="Bottom">
    <TextBlock Foreground="Black">Dock = "Bottom"</TextBlock>
  </Border>
  <Border Width="100" Background="PaleGreen" DockPanel.Dock="Left">
    <TextBlock Foreground="Black">Dock = "Left"</TextBlock>
  </Border>
  <Border Background="White">
    <TextBlock Foreground="Black">
      This content will "Fill" the remaining space
    </TextBlock>
  </Border>
</DockPanel><StackPanel Orientation="Horizontal"> <RadioButton Margin="4">test1</RadioButton> <RadioButton Margin="4">test2</RadioButton> <RadioButton Margin="4">test3</RadioButton> </StackPanel>
<StackPanel Orientation="Vertical"> <RadioButton Margin="4">test1</RadioButton> <RadioButton Margin="4">test2</RadioButton> <RadioButton Margin="4">test3</RadioButton> </StackPanel>
<WrapPanel Orientation="Horizontal"> <Button Width="26" Height="26" Margin="4" Content="0"></Button> <Button Width="26" Height="26" Margin="4" Content="1"></Button> <Button Width="26" Height="26" Margin="4" Content="2"></Button> ・・・ <Button Width="26" Height="26" Margin="4" Content="7"></Button> <Button Width="26" Height="26" Margin="4" Content="8"></Button> <Button Width="26" Height="26" Margin="4" Content="9"></Button> </WrapPanel>
<WrapPanel Orientation="Vertical"> <Button Width="26" Height="26" Margin="4" Content="0"></Button> <Button Width="26" Height="26" Margin="4" Content="1"></Button> <Button Width="26" Height="26" Margin="4" Content="2"></Button> ・・・ <Button Width="26" Height="26" Margin="4" Content="7"></Button> <Button Width="26" Height="26" Margin="4" Content="8"></Button> <Button Width="26" Height="26" Margin="4" Content="9"></Button> </WrapPanel>
<UniformGrid Rows="3" Columns="4"> <Button Width="26" Height="26" Margin="4" Content="0"></Button> <Button Width="26" Height="26" Margin="4" Content="1"></Button> <Button Width="26" Height="26" Margin="4" Content="2"></Button> ・・・ <Button Width="26" Height="26" Margin="4" Content="7"></Button> <Button Width="26" Height="26" Margin="4" Content="8"></Button> <Button Width="26" Height="26" Margin="4" Content="9"></Button> </UniformGrid>
<UniformGrid Rows="4" Columns="3"> <Button Width="26" Height="26" Margin="4" Content="0"></Button> <Button Width="26" Height="26" Margin="4" Content="1"></Button> <Button Width="26" Height="26" Margin="4" Content="2"></Button> ・・・ <Button Width="26" Height="26" Margin="4" Content="7"></Button> <Button Width="26" Height="26" Margin="4" Content="8"></Button> <Button Width="26" Height="26" Margin="4" Content="9"></Button> </UniformGrid>
<Grid Width="250" Height="100">
  <Grid.ColumnDefinitions>
    <ColumnDefinition />
    <ColumnDefinition />
    <ColumnDefinition />
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition />
    <RowDefinition />
    <RowDefinition />
  </Grid.RowDefinitions>
  <TextBlock Grid.ColumnSpan="3" Grid.Row="0">2005 Products Shipped</TextBlock>
  <TextBlock Grid.Row="1" Grid.Column="0">Quarter 1</TextBlock>
  <TextBlock Grid.Row="1" Grid.Column="1">Quarter 2</TextBlock>
  <TextBlock Grid.Row="1" Grid.Column="2">Quarter 3</TextBlock>
  <TextBlock Grid.Row="2" Grid.Column="0">50000</TextBlock>
  <TextBlock Grid.Row="2" Grid.Column="1">100000</TextBlock>
  <TextBlock Grid.Row="2" Grid.Column="2">150000</TextBlock>
  <TextBlock Grid.ColumnSpan="3" Grid.Row="3">Total Units: 300000</TextBlock>
</Grid><Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="1*"></ColumnDefinition>
    <ColumnDefinition Width="2*"></ColumnDefinition>
    <ColumnDefinition Width="3*"></ColumnDefinition>
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Height="1*"></RowDefinition>
    <RowDefinition Height="2*"></RowDefinition>
    <RowDefinition Height="3*"></RowDefinition>
  </Grid.RowDefinitions>
</Grid>ココでは、「外観」に関する設定を行う「スタイル」と「テンプレート」について説明する。
WPF / Silverlightで外観をカスタマイズする仕組みのこと。
「スタイル」は、UI要素の「依存関係プロパティ」の一括管理機能を持ち、これを使用して「外観」に統一性を持たせるための機能である。
「スタイル」は、Style型のオブジェクトであり、各UI要素(FrameworkElement? or FrameworkContentElement?)のStyleプロパティに指定可能である。
<Grid> <Ellipse Fill="Blue" Height="80" Width="160"/> </Grid>
<Grid>
  <Ellipse>
    <Ellipse.Style>
      <Style TargetType="Ellipse">
        <Setter Property="Fill" Value="Blue"/>
        <Setter Property="Height" Value="80"/>
        <Setter Property="Width" Value="160"/>
      </Style>
    </Ellipse.Style>
  </Ellipse>
</Grid>  <StackPanel.Resources>
    <Style x:Key="EllipseStyle" TargetType="Ellipse">
      <Setter Property="Fill" Value="Blue"/>
      <Setter Property="Height" Value="80"/>
      <Setter Property="Width" Value="160"/>
    </Style>
  </StackPanel.Resources>
  <Ellipse Style="{StaticResource EllipseStyle}"/>
  <Ellipse Style="{StaticResource EllipseStyle}"/>
</StackPanel><StackPanel>
  <StackPanel.Resources>
    <Style x:Key="ShapeStyle" TargetType="Shape">
      <Setter Property="Fill" Value="Blue"/>
      <Setter Property="Height" Value="80"/>
      <Setter Property="Width" Value="160"/>
    </Style>
  </StackPanel.Resources>
  <Ellipse Style="{StaticResource ShapeStyle}"/>
  <Rectangle Style="{StaticResource ShapeStyle}"/>
</StackPanel><StackPanel>
  <StackPanel.Resources>
    <Style TargetType="Ellipse">
      <Setter Property="Fill" Value="Blue"/>
      <Setter Property="Height" Value="80"/>
      <Setter Property="Width" Value="160"/>
    </Style>
  </StackPanel.Resources>
  <Ellipse/>
  <Ellipse/>
</StackPanel>(Silverlight 2のStyleクラスにはBasedOn?プロパティが存在しなかったが、Silverlight 3で追加されている)
<StackPanel>
  <StackPanel.Resources>
    <Style x:Key="EllipseBaseStyle" TargetType="Ellipse">
      <Setter Property="Fill" Value="Blue"/>
      <Setter Property="Height" Value="80"/>
      <Setter Property="Width" Value="160"/>
    </Style>
    <Style x:Key="EllipseInheritedStyle" TargetType="Ellipse"
      BasedOn="{StaticResource EllipseBaseStyle}">
      <Setter Property="Stroke" Value="Yellow"/>
      <Setter Property="StrokeThickness" Value="10"/>
    </Style>
  </StackPanel.Resources>
  <Ellipse Style="{StaticResource EllipseBaseStyle}"/>
  <Ellipse Style="{StaticResource EllipseInheritedStyle}"/>
 </StackPanel><Window.Resources>
  <ResourceDictionary Source="Dictionary1.xaml"/>
</Window.Resources>
<StackPanel>
  <StackPanel.Resources>
    <Style x:Key="EllipseInheritedStyle" TargetType="Ellipse"
      BasedOn="{StaticResource EllipseBaseStyle}">
      <Setter Property="Stroke" Value="Yellow"/>
      <Setter Property="StrokeThickness" Value="10"/>
    </Style>
  </StackPanel.Resources>
  <Ellipse Style="{StaticResource EllipseBaseStyle}"/>
  <Ellipse Style="{StaticResource EllipseInheritedStyle}"/>
</StackPanel><ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Style x:Key="EllipseBaseStyle" TargetType="Ellipse">
    <Setter Property="Fill" Value="Blue"/>
    <Setter Property="Height" Value="80"/>
    <Setter Property="Width" Value="160"/>
  </Style>
</ResourceDictionary>の方法を、「スタイル」でも応用可能である。
<StackPanel>
  <Ellipse Style="{DynamicResource MyEllipseStyle}"/>
  <Button Content="青" Height="23" Name="button1" Width="75" Click="button1_Click" />
  <Button Content="赤" Height="23" Name="button2" Width="75" Click="button2_Click" />
</StackPanel><ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Style x:Key="MyEllipseStyle" TargetType="Ellipse">
    <Setter Property="Fill" Value="Blue"/>
    <Setter Property="Height" Value="80"/>
    <Setter Property="Width" Value="160"/>
  </Style>
</ResourceDictionary><ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="MyEllipseStyle" TargetType="Ellipse">
        <Setter Property="Fill" Value="Red"/>
        <Setter Property="Height" Value="160"/>
        <Setter Property="Width" Value="80"/>
    </Style>
</ResourceDictionary>public partial class Window1 : Window {
  public Window1() {
    InitializeComponent();
    this.LoadResourceDictionary("Dictionary1.xaml");
  }
  private void button1_Click(object sender, RoutedEventArgs e) {
    this.LoadResourceDictionary("Dictionary1.xaml");
  }
  private void button2_Click(object sender, RoutedEventArgs e) {
    this.LoadResourceDictionary("Dictionary2.xaml");
  }
  private void LoadResourceDictionary(string name) {
    ResourceDictionary dictionary =
      (ResourceDictionary)Application.LoadComponent(new Uri(name, UriKind.Relative));
    if (dictionary != null) Application.Current.Resources = dictionary;
  }
}WPF / Silverlightで外観をカスタマイズする仕組みのこと。
このため、WPFのUIコントロールはコントロールの「外観」を自由に変更でき、柔軟性が非常に高くなっている。
| # | コントロールのクラス型 | コンテンツを設定するプロパティ | 説明 | 
| 1 | ContentControl?クラス | Contentプロパティ | ContentControl?.Contentプロパティにコントロールの外観を設定できる。 | 
| 2 | ItemsControl?クラス | Itemsプロパティ | ItemsControl?.Itemsプロパティにコントロールの外観を設定できる。 | 
| # | テンプレートを設定するプロパティ | テンプレートのクラス型 | 説明 | ||
| 1 | Control.Template | ControlTemplate | Controlコントロールの全体の外観をカスタマイズする「テンプレート」を定義する際に使用する。 各種プロパティを表示する場合、各種プロパティを表示するための要素をControlTemplate?クラスに含める。  | ||
| 1-1 | ContentControl?の(Control. )Templateプロパティ | Contentプロパティを表示する場合、ContentControl?.Contentプロパティを表示するContentPresenter?クラスをControlTemplate?クラスに含める。 | |||
| 1-2 | ItemsControl?の(Control. )Templateプロパティ | Itemsプロパティを表示する場合、ItemsControl?.Itemsプロパティを表示するItemsPresenter?クラスをControlTemplate?クラスに含める。 | |||
| 2 | XXXX.XXXXTemplate | DataTemplate | ContentControl?やItemsControl?コントロールのデータの外観をカスタマイズする「テンプレート」を定義する際に使用する。 各種データを表示する場合、各種データを表示するための要素をDataTemplate?クラスに含める。  | ||
| 2-1 | ContentControl.ContentTemplate | ContentControl?.ContentTemplate?プロパティには、各種データを表示するための要素を含めたDataTemplate?クラスを設定する。 | |||
| 2-2 | ItemsControl.ItemTemplate | ItemsControl?.ItemTemplate?プロパティには、各種データを表示するための要素を含めたDataTemplate?クラスを設定する。 | |||
| 3 | その他 | - | 種々のコントロールの個別領域の外観をカスタマイズする「テンプレート」を設定する際に使用する。 | ||
| 3-1 | ItemsControl.ItemsPanel | ItemsPanelTemplate | Itemsプロパティに設定したコレクションの並びをカスタマイズできる。 | ||
| 3-2 | HeaderedContentControl.HeaderTemplate | DataTemplate | ヘッダ・データの表示をカスタマイズできる。 | ||
| 3-3 | GridViewColumn.CellTemplate | セル・データの表示をカスタマイズできる。 | |||
また、親コントロールに適用した、「テンプレート」の値を
Contentプロパティ(またはItemsプロパティ)を含む
プロパティ値に反映させるにめには、下記の3通りの方法を選択的に使用できる。
参考 : FrameworkTemplate? クラス (System.Windows)
https://msdn.microsoft.com/ja-jp/library/system.windows.frameworktemplate(v=vs.110).aspx
参考 : 【WPF】Presenter(?)クラスを収集と考察。 | 創造的プログラミングと粘土細工
http://pro.art55.jp/?eid=931821
<object property="{TemplateBinding TargetProperty }" .../><Binding RelativeSource="{RelativeSource TemplatedParent}" .../>
<object property="{Binding RelativeSource={RelativeSource TemplatedParent} ...}" .../><StackPanel>
  <TextBlock Text="{Binding RelativeSource
    ={RelativeSource Self}, Path=FontFamily}" />・・・(1)
  <Border Background="Black" Height="5"/>
  <TextBlock Text="{Binding RelativeSource
    ={RelativeSource AncestorType={x:Type StackPanel}},Path=Orientation}" />・・・(2)
  <Border Background="Black" Height="5"/>
  <Button Content="Hello world">
    <Button.Template>
      <ControlTemplate TargetType="{x:Type Button}">
        <ContentPresenter Content="{Binding RelativeSource
          ={RelativeSource TemplatedParent}, Path=Content}" />・・・(3)
      </ControlTemplate>
    </Button.Template>
  </Button>
</StackPanel><Grid>
  <Button Margin="5" Width="100" Height="100" Content="ボタン">
    <Button.Template>
      <ControlTemplate TargetType="Button">
        <Grid>
          <Rectangle Fill="Blue"/>
          <Ellipse Fill="Red"/>
          <ContentPresenter
            HorizontalAlignment="Center"
            VerticalAlignment="Center"/>
        </Grid>
      </ControlTemplate>
    </Button.Template>
  </Button>
</Grid><Grid>
  <Button Margin="5" Width="100" Height="100" Content="ボタン">
    <Button.Template>
      <ControlTemplate TargetType="Button">
        <Grid>
          <Rectangle Fill="Blue"/>
          <Ellipse Fill="Red"/>
          <TextBlock
            Text="{TemplateBinding Content}"
            HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Grid>
      </ControlTemplate>
    </Button.Template>
  </Button>
</Grid><Grid>
  <Button Margin="5" Width="100" Height="100" Content="ボタン">
    <Button.Template>
      <ControlTemplate>
        <Grid>
          <Rectangle Fill="Blue"/>
          <Ellipse Fill="Red"/>
          <TextBlock
            Text="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}"
            HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Grid>
      </ControlTemplate>
    </Button.Template>
  </Button>
</Grid><Window.Resources>
  <Style x:Key="buttonTemplate" TargetType="Button">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="Button">
          <Grid>
            <Rectangle Fill="Blue"/>
            <Ellipse Fill="Red"/>
            <ContentPresenter
              HorizontalAlignment="Center"
              VerticalAlignment="Center"/>
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</Window.Resources>
<StackPanel Orientation="Vertical">
  <Button Margin="5" Width="100" Height="100">ボタン1</Button>
  <Button Margin="5" Width="100" Height="100">ボタン2</Button>
  <Button Margin="5" Width="100" Height="100"
    Style="{StaticResource buttonTemplate}">ボタン3</Button>
</StackPanel><Window.Resources>
  <Style TargetType="Button">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="Button">
          <Grid>
            <Rectangle Fill="Blue"/>
            <Ellipse Fill="Red"/>
            <ContentPresenter
              HorizontalAlignment="Center"
              VerticalAlignment="Center"/>
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</Window.Resources>
<StackPanel Orientation="Vertical">
  <Button Margin="5" Width="100" Height="100">ボタン1</Button>
  <Button Margin="5" Width="100" Height="100">ボタン2</Button>
  <Button Margin="5" Width="100" Height="100">ボタン3</Button>
</StackPanel><Window.Resources>
  <ControlTemplate x:Key="buttonTemplate" TargetType="Button">
    <Grid>
      <Rectangle Fill="Blue"/>
      <Ellipse Fill="Red"/>
      <ContentPresenter
        HorizontalAlignment="Center"
        VerticalAlignment="Center"/>
    </Grid>
  </ControlTemplate>
  <Style TargetType="Button">
    <Setter Property="Template" Value="{StaticResource buttonTemplate}"/>
  </Style>
</Window.Resources>
<StackPanel Orientation="Vertical">
  <Button Margin="5" Width="100" Height="100">ボタン1</Button>
  <Button Margin="5" Width="100" Height="100">ボタン2</Button>
  <Button Margin="5" Width="100" Height="100">ボタン3</Button>
</StackPanel><Window.Resources> <ResourceDictionary Source="TemplateStyleDictionary.xaml"/> </Window.Resources> <StackPanel Orientation="Vertical"> <Button Margin="5" Width="100" Height="100">ボタン1</Button> <Button Margin="5" Width="100" Height="100">ボタン2</Button> <Button Margin="5" Width="100" Height="100">ボタン3</Button> </StackPanel>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <ControlTemplate x:Key="buttonTemplate" TargetType="Button">
    <Grid>
      <Rectangle Fill="Blue"/>
      <Ellipse Fill="Red"/>
      <ContentPresenter
        HorizontalAlignment="Center"
        VerticalAlignment="Center"/>
    </Grid>
  </ControlTemplate>
  <Style TargetType="Button">
    <Setter Property="Template" Value="{StaticResource buttonTemplate}"/>
  </Style>
</ResourceDictionary><Grid>
  <Button Content="Click Here"
    Margin="5" Width="100" Height="100">
    <Button.Template>
      <ControlTemplate TargetType="Button">
        <Grid>
          <Rectangle Fill="Blue"/>
          <Ellipse Fill="Red"/>
          <ContentPresenter
            HorizontalAlignment="Center"
            VerticalAlignment="Center"/>
        </Grid>
      </ControlTemplate>
    </Button.Template>
    <Button.ContentTemplate>
      <DataTemplate>
        <Grid>
          <TextBlock Text="{Binding}"/>
        </Grid>
      </DataTemplate>
    </Button.ContentTemplate>
  </Button>
</Grid><TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=xxxx}"/>などの記述方法がある。
<Grid>
  <StackPanel x:Name="stackPanel1">
    <ListBox x:Name="ListBox1" ItemsSource="{Binding}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <Border BorderBrush ="Black" BorderThickness ="1" Margin="5">
            <StackPanel Orientation="Horizontal" Height="120" Width="250">
              <Image Height="100" Source="{Binding Path=[Image]}" />
              <TextBlock Text="{Binding Path=[Text]}"  VerticalAlignment="Center" />
            </StackPanel>
          </Border>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
  </StackPanel>
</Grid>public Window1() {
  InitializeComponent();
  List<Dictionary<string, string>> lst
    = new List<Dictionary<string, string>>();
  Dictionary<string, string> dic = null;
  dic = new Dictionary<string, string>();
  dic["Image"] = @".\Blue hills.jpg";
  dic["Text"] = "Blue hills";
  lst.Add(dic);
  dic = new Dictionary<string, string>();
  dic["Image"] = @".\Sunset.jpg";
  dic["Text"] = "Sunset";
  lst.Add(dic);
  dic = new Dictionary<string, string>();
  dic["Image"] = @".\Water lilies.jpg";
  dic["Text"] = "Water lilies";
  lst.Add(dic);
  dic = new Dictionary<string, string>();
  dic["Image"] = @".\Winter.jpg";
  dic["Text"] = "Winter";
  lst.Add(dic);
  this.stackPanel1.DataContext = lst;
}Dictionary<string, string> dic = (Dictionary<string, string>)this.ListBox1.SelectedValue;
<Window.Resources>
  <DataTemplate x:Key="listBoxStyle">
    <Border BorderBrush ="Black" BorderThickness ="1" Margin="5">
      <StackPanel Orientation="Horizontal" Height="120" Width="250">
        <Image Height="100" Source="{Binding Path=Image}" /> ・・・ 通常のプロパティの場合の記述方法
        <TextBlock Text="{Binding Path=[Text]}"  VerticalAlignment="Center" /> ・・・ インデクサの場合の記述方法
      </StackPanel>
    </Border>
  </DataTemplate>
</Window.Resources>
<Grid>
  <StackPanel x:Name="stackPanel1">
    <ListBox x:Name="ListBox1"
      ItemsSource="{Binding}" ItemTemplate="{StaticResource listBoxStyle}"/>
  </StackPanel>
</Grid>public Window1() {
  InitializeComponent();
  DataTable dt = new DataTable();
  dt.Columns.Add(new DataColumn("Image"));
  dt.Columns.Add(new DataColumn("Text"));
  DataRow dr = null;
  dr = dt.NewRow();
  dr["Image"] = @".\Blue hills.jpg";
  dr["Text"] = "Blue hills";
  dt.Rows.Add(dr);
 ・・・
  dr = dt.NewRow();
  dr["Image"] = @".\Winter.jpg";
  dr["Text"] = "Winter";
  dt.Rows.Add(dr);
  this.stackPanel1.DataContext = dt;
}DataRow dr = (DataRow)this.ListBox1.SelectedValue;
<Grid>
  <StackPanel x:Name="stackPanel1">
    <ListBox x:Name="ListBox1" ItemsSource="{Binding}"
      SelectedValuePath="Value" DisplayMemberPath="Display" />
    <Button Click="Button_Click">選択値</Button>
  </StackPanel>
</Grid>public Window1() {
  InitializeComponent();
  DataTable dt = new DataTable();
  dt.Columns.Add(new DataColumn("Value"));
  dt.Columns.Add(new DataColumn("Display"));
  DataRow dr = null;
  dr = dt.NewRow();
  dr["Value"] = "0001";
  dr["Display"] = "0001の表示";
  dt.Rows.Add(dr);
 ・・・
  dr = dt.NewRow();
  dr["Value"] = "0004";
  dr["Display"] = "0004の表示";
  dt.Rows.Add(dr);
  this.stackPanel1.DataContext = dt;
}private void Button_Click(object sender, RoutedEventArgs e) {
  MessageBox.Show(this.ListBox1.SelectedValue.ToString());
}<Grid>
  <ListBox>
    <ListBox.Template>
      <ControlTemplate>
        <ItemsPresenter Margin="5" HorizontalAlignment="Center"/>
      </ControlTemplate>
    </ListBox.Template>
    <ListBoxItem>1</ListBoxItem>
    <ListBoxItem>2</ListBoxItem>
    <ListBoxItem>3</ListBoxItem>
  </ListBox>
</Grid><Grid>
  <ListBox>
    <ListBox.Template>
      <ControlTemplate TargetType="ListBox">
        <ItemsPresenter Margin="5" HorizontalAlignment="Center"/>
      </ControlTemplate>
    </ListBox.Template>
    <ListBox.ItemsPanel>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"/>
      </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBoxItem>1</ListBoxItem>
    <ListBoxItem>2</ListBoxItem>
    <ListBoxItem>3</ListBoxItem>
  </ListBox>
</Grid><Grid>
  <ListBox Name="listBox1" ItemsSource="{Binding}">
    <ListBox.Template>
      <ControlTemplate>
        <StackPanel>
          <StackPanel  Orientation="Horizontal" Background="Gray">
            <TextBlock Width="100" Text="ヘッダ1"/>
            <TextBlock Width="100" Text="ヘッダ2"/>
          </StackPanel>
          <ItemsPresenter/>	・・・ItemsPresenterを忘れないよう設定する。
        </StackPanel>
      </ControlTemplate>
    </ListBox.Template>
    <ListBox.ItemTemplate>
      <DataTemplate>
        <StackPanel  Orientation="Horizontal">
          <TextBlock Width="100" Text="{Binding Path=[data1]}"/>
          <TextBlock Width="100" Text="{Binding Path=[data2]}"/>
        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</Grid>public Window1() {
  InitializeComponent();
  List<Dictionary<string, string>> lst = new List<Dictionary<string, string>>();
  Dictionary<string, string> dic = null;
  dic = new Dictionary<string, string>();
  dic["data1"] = "データ11";
  dic["data2"] = "データ11";
  lst.Add(dic);
  dic = new Dictionary<string, string>();
  dic["data1"] = "データ21";
  dic["data2"] = "データ22";
  lst.Add(dic);
  this.listBox1.DataContext = lst; 
}<Grid>
  <StackPanel x:Name="stackPanel1">
    <Button x:Name="button1" Click="button1_Click">選択</Button>
    <ListBox x:Name="ListBox1" ItemsSource="{Binding}">
      <ListBox.Template>
        <ControlTemplate>
          <ItemsPresenter Margin="5" HorizontalAlignment="Center"/>
        </ControlTemplate>
      </ListBox.Template>
      <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
          <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
      </ListBox.ItemsPanel>
      <ListBox.ItemTemplate>
        <DataTemplate>
          <Border BorderBrush ="Black" BorderThickness ="1" Margin="5">
            <StackPanel Orientation="Horizontal" Height="120" Width="250">
              <Image Height="100" Source="{Binding Path=[Image]}" />
              <TextBlock Text="{Binding Path=[Text]}"  VerticalAlignment="Center" />
            </StackPanel>
          </Border>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
  </StackPanel>
</Grid>public Window1() {
  InitializeComponent();
  DataTable dt = new DataTable();
  dt.Columns.Add(new DataColumn("Image"));
  dt.Columns.Add(new DataColumn("Text"));
  DataRow dr = null;
  dr = dt.NewRow();
  dr["Image"] = @".\Blue hills.jpg";
  dr["Text"] = "Blue hills";
  dt.Rows.Add(dr);
 ・・・
  dr = dt.NewRow();
  dr["Image"] = @".\Winter.jpg";
  dr["Text"] = "Winter";
  dt.Rows.Add(dr);
  this.stackPanel1.DataContext = dt;
}
private void Button_Click(object sender, RoutedEventArgs e) {
  MessageBox.Show(this.ListBox1.SelectedValue.ToString());
}<Window.Resources>
  <Style x:Key="listViewItemStyle" TargetType="ListViewItem" >
    <Setter Property="BorderBrush" Value="Gray"/>
    <Setter Property="BorderThickness" Value="2"/>
  </Style>
  <DataTemplate x:Key="listViewHeaderTemplate">
    <TextBlock FontSize="16" Foreground="Navy" Text="{Binding}"/>
  </DataTemplate>
  <DataTemplate x:Key="listViewCellStyle">
    <Border BorderBrush ="Black" BorderThickness ="5" Margin="5">
      <Image Height="100" Source="{Binding Path=Image}" />
    </Border>
  </DataTemplate>
</Window.Resources>
<StackPanel x:Name="stackPanel1">
  <ListView x:Name="listView1" ItemsSource="{Binding}"
    ItemContainerStyle="{StaticResource listViewItemStyle}">
    <ListView.View>
      <GridView ColumnHeaderTemplate="{StaticResource listViewHeaderTemplate}">
        <GridViewColumn Header="名称" 
          DisplayMemberBinding="{Binding Path=Text}" />
        <GridViewColumn Header="画像"
          CellTemplate="{StaticResource listViewCellStyle}"/>
      </GridView>
    </ListView.View>
  </ListView>
</StackPanel>public Window1() {
  InitializeComponent();
  DataTable dt = new DataTable();
  dt.Columns.Add(new DataColumn("Image"));
  dt.Columns.Add(new DataColumn("Text"));
  DataRow dr = null;
  dr = dt.NewRow();
  dr["Image"] = @".\Blue hills.jpg";
  dr["Text"] = "Blue hills";
  dt.Rows.Add(dr);
 ・・・
  this.stackPanel1.DataContext = dt;
}ものである。
<Window.Resources>
  <Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="LightYellow" />
    <!--IsPressed = True で、背景色変更-->
    <Style.Triggers>
      <Trigger Property="IsPressed" Value="True">
        <Setter Property="Background" Value="LightBlue" />
      </Trigger>
    </Style.Triggers>
  </Style>
  <Style x:Key="ButtonStyle2" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="LightYellow" />
    <!--IsMouseOver = True で、背景色変更-->
    <Style.Triggers>
      <Trigger Property="IsMouseOver" Value="True">
        <Setter Property="Background" Value="LightBlue" />
      </Trigger>
    </Style.Triggers>
  </Style>
  <Style x:Key="ButtonStyle3" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="LightYellow" />
    <!--IsMouseOver、IsFocused = True で、背景色変更-->
    <Style.Triggers>
      <MultiTrigger>
        <MultiTrigger.Conditions>
          <Condition Property="IsMouseOver" Value="True"/>
          <Condition Property="IsFocused" Value="True"/>
        </MultiTrigger.Conditions>
        <Setter Property="Background" Value="LightBlue" />
      </MultiTrigger >
    </Style.Triggers>
  </Style>
</Window.Resources>
<Grid>
  <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
  </Grid.RowDefinitions>
  <Button Style="{StaticResource ButtonStyle1}" Grid.Row="0" >Button(IsPressed)</Button>
  <Button Style="{StaticResource ButtonStyle2}" Grid.Row="1" >Button(IsMouseOver)</Button>
  <Button Style="{StaticResource ButtonStyle3}" Grid.Row="2" >Button(IsMouseOver & IsFocused)</Button>
</Grid><Window.Resources>
  <my:Places x:Key="PlacesData"/>
  <Style TargetType="ListBoxItem">
    <Style.Triggers>
      <!--DataTrigger(Condition×1)-->
      <!-- State = WA の行は文字色 = 赤-->
      <DataTrigger Binding="{Binding Path=State}" Value="WA">
        <Setter Property="Foreground" Value="Red" />
      </DataTrigger>
      <!--MultiDataTrigger(Condition×n)-->
      <!-- Name = Portland, State = OR の行は背景色 = 黄-->
      <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
          <Condition Binding="{Binding Path=Name}" Value="Portland" />
          <Condition Binding="{Binding Path=State}" Value="OR" />
        </MultiDataTrigger.Conditions>
        <Setter Property="Background" Value="Yellow" />
      </MultiDataTrigger>
    </Style.Triggers>
  </Style>
  <DataTemplate DataType="{x:Type my:Place}">
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
      <TextBlock Width="20"/>
      <TextBlock Width="100" Text="{Binding Path=Name}"/>
      <TextBlock Width="20"/>
      <TextBlock Text="{Binding Path=State}"/>
    </StackPanel>
  </DataTemplate>
</Window.Resources>
<StackPanel>
  <TextBlock Margin="5" HorizontalAlignment="Center">Data Trigger Sample</TextBlock>
  <ListBox HorizontalAlignment="Stretch"
           ItemsSource="{Binding Source={StaticResource PlacesData}}"/>
</StackPanel>/// <summary>Place</summary>
public class Place {
  /// <summary>名前</summary>
  private string _name;
  /// <summary>状態</summary>
  private string _state;
  /// <summary>名前</summary>
  public string Name {
    get { return _name; }
    set { _name = value; }
  }
  /// <summary>状態</summary>
  public string State {
    get { return _state; }
    set { _state = value; }
  }
  /// <summary>コンストラクタ</summary>
  public Place(string name, string state) {
    this._name = name;
    this._state = state;
  }
}
public class Places : ObservableCollection<Place> {
  /// <summary>コンストラクタで</summary>
  public Places() {
    this.Add(new Place("Bellevue", "WA"));
    this.Add(new Place("Gold Beach", "OR"));
    this.Add(new Place("Kirkland", "WA"));
    this.Add(new Place("Los Angeles", "CA"));
    this.Add(new Place("Portland", "ME"));
    this.Add(new Place("Portland", "OR"));
    this.Add(new Place("Redmond", "WA"));
    this.Add(new Place("San Diego", "CA"));
    this.Add(new Place("San Francisco", "CA"));
    this.Add(new Place("San Jose", "CA"));
    this.Add(new Place("Seattle", "WA"));
  }
}Tags: :.NET開発, :UIサブシステム, :WPF/Silverlight, XAML