[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]

-[[戻る>XAMLの書き方]]

* 目次 [#i78ae0d5]
#contents

*概要 [#d37660b8]
XAMLは、XMLをベースとしており、XAMLの各要素からCLRオブジェクトをインスタンス化し、「要素ツリー」を構築できる。

ここでは、WPFのXAMLの書き方を通して、
-XAMLの基礎
-XAMLによるUI設計方法
-XAMLによるUI開発方法

を説明する。

*名前空間 [#x46c4d22]
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"

-XML名前空間の簡単な説明~
http://www.kanzaki.com/docs/sw/names.html

**WPF名前空間 [#u9e59dba]
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オブジェクトを利用できる。

**XAML名前空間 [#f7e47ba4]
3行目のXML名前空間の宣言(xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml")では、~
URIにマップされた共通的なXAMLの言語機能がXML名前空間(x)として割り当てられている。~
これにより、「x:」というプレフィックスを使用することで、「[[言語機能>#n6cf5f58]]」で説明する、XAMLの言語機能を使用できるようになる。

**CLR名前空間 [#b9a3d659]
CLR名前空間について以下を例にとって説明する。

***(1) [#j611ebcc]

-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名前空間の宣言が追加される。

-MSDN > .NET Frameworkクラス ライブラリ > System.Windows.Markup.XmlAttributeProperties.XmlnsDefinitionプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.markup.xmlattributeproperties.xmlnsdefinition.aspx

なお、XML名前空間には一意の名前を自由に付与でき(上記の例ではigDP)、このプレフィックスを使用することで、XAMLからUIコンポーネントのCLRオブジェクトを利用できる。

***(2) [#y81abbb2]
この他に、URIとしてCLR名前空間とアセンブリを直接指定する方法もある。

-CLR名前空間の宣言
 xmlns:sys="clr-namespace:(CLR名前空間);assembly=(アセンブリ名)"
--例1:サードパーティ製品
 <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"/> <--- 名前空間の使用例
--例2:.NET Framework
 <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}"> <--- 名前空間の使用例
--例3:自作の同一プロジェクトのクラス
 <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"/> <--- 名前空間の使用例

-この方法では、「clr-namespace」、「assembly」などの定義済みトークンを使用する。
--当該プロジェクト中のCLR名前空間を指定する場合は、「assembly」トークンは省略できる。
--XML名前空間には一意の名前を自由に付与でき、このプレフィックスを使用することで、XAMLからUIコンポーネントのCLRオブジェクトを利用できる。

-製品並みのカスタムのUIコントロールを開発・使用するなどの目的を除いて、CLRクラスを開発しXAMLから使用する場合、
--一般的には「clr-namespace、assembly」の定義済みトークンを使用する。
--ただし、この方法は、1つのCLR名前空間に対して、1つのXML名前空間しか割り当てられない
--(XmlnsDefinitionアセンブリ属性を使用すると、1つのXML名前空間に複数のCLR名前空間を割り当てられる)。

***参考 [#v51c1b09]
-MSDN > WPFの基礎 > WPFのXAML > XAML名前空間およびWPF XAMLの名前空間の割り当て~
http://msdn.microsoft.com/ja-jp/library/ms747086.aspx

*言語機能 [#ad009a58]
XAMLの言語機能である
-「[[ディレクティブ>#cd4daa01]]」
-「[[マークアップ拡張>#hc49ac25]]」

について説明する。

-MSDN > .NET Framework XAMLサービスの概念説明のドキュメント > XAML名前空間 (x:) 言語機能~
http://msdn.microsoft.com/ja-jp/library/ms753327.aspx

**ディレクティブ [#j78f478c]
XAMLの言語機能が提供する各種ディレクティブについて説明する。

|項番|ディレクティブ|説明|h
|~|~|例|h
|1|x:Class|XAML上から分離クラス(コードビハインド)のクラス名を定義する。|
|~|~|<Window x:Class="WpfApplication1.Window1"|
|2|x:Subclass|パーシャル クラスをサポートしない言語で使用する。通常は利用しない。|
|~|~|-|
|3|x: ClassModifier|クラスのアクセスレベルを変更する。通常は利用しない。|
|~|~|-|
|4|x:Code|XAML上にインラインコードを実装する場合に使用する。通常は利用しない。|
|~|~|<Grid>&br;&nbsp;&nbsp;<x:Code>&br;&nbsp;&nbsp;&nbsp;&nbsp;<![CDATA[&br;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;button1_Click(object&nbsp;sender,&nbsp;RoutedEventArgs&nbsp;e)&nbsp;{&br;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;button1.Content&nbsp;=&nbsp;"Hello&nbsp;World";&br;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&br;&nbsp;&nbsp;&nbsp;&nbsp;]]>&br;&nbsp;&nbsp;</x:Code>&br;&nbsp;&nbsp;<Button&nbsp;Name="button1"&nbsp;Click="button1_Click">Button</Button>&br;</Grid>|
|5|x:FieldModifier|プロパティのアクセスレベルを変更する。通常は利用しない。|
|~|~|-|
|6|x:Key|XAMLで定義された各種「リソース」を識別する。下記は、x:Keyを使用して「スタイル」の「リソース」をボタンに「データ バインディング」する例。|
|~|~|<Window.Resources>&br;&nbsp;&nbsp;<Style&nbsp;x:Key="buttonStyle"&nbsp;TargetType="{x:Type&nbsp;Button}">&br;&nbsp;&nbsp;&nbsp;&nbsp;<Setter&nbsp;Property="Background"&nbsp;Value="LightYellow"&nbsp;/>&br;&nbsp;&nbsp;</Style>&br;</Window.Resources>&br;<Grid>&br;&nbsp;&nbsp;<Button&nbsp;Style="{StaticResource&nbsp;buttonStyle}">Hello&nbsp;Style</Button>&br;</Grid>|
|7|x:Name|XAMLで生成したCLRオブジェクトに名前を付与する。Name属性と差異は無い。|
|~|~|<Button&nbsp;x:Name="button1">&br;&nbsp;&nbsp;&nbsp;Click&nbsp;Here&br;</Button>|
|8|x:Shared|静的なリソースを、取得の度に生成する場合に使用する。通常は利用しない。&br;※&nbsp;true&nbsp;:&nbsp;静的(全てのインスタンスは同じ)&br;&nbsp;&nbsp;&nbsp;false&nbsp;:&nbsp;動的(取得の度に生成する)&br;&nbsp;&nbsp;&nbsp;既定値&nbsp;:&nbsp;true|
|~|~|-|
|9|x:TypeArguments|ジェネリックの型引数をコンストラクタに渡す。&br;(.NET Framework 4.0のXAML 2009からのサポート)|
|~|~|<!--&nbsp;XAML&nbsp;2009&nbsp;-->&br;<ObservableCollection&nbsp;x:TypeArguments="Employee">&br;&nbsp;&nbsp;<l:Employee&nbsp;FirstName="John"&nbsp;Name="Doe"&nbsp;/>&br;&nbsp;&nbsp;<l:Employee&nbsp;FirstName="Tim"&nbsp;Name="Smith"&nbsp;/>&br;</ObservableCollection>|
|10|x:Uid|ローカライゼーションのプロセスとツールによって使用される一意識別子を指定する 。|
|~|~|-|
|11|xml:lang|カルチャ情報を宣言する。|
|~|~|<Window&nbsp;x:Class="WpfApplication1.Window1"&br;&nbsp;&nbsp;xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&br;&nbsp;&nbsp;xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&br;&nbsp;&nbsp;xml:lang="ja-JP"|

-MSDN > Windows Presentation Foundation > グローバライズとローカライズ > WPFのグローバリゼーション~
http://msdn.microsoft.com/ja-jp/library/ms745650.aspx

**マークアップ拡張 [#b565ab69]
XAMLの言語機能が提供する各種「マークアップ拡張」について説明する。~
通常、「マークアップ拡張」は、「{」と「}」の2つの中括弧を使用することでXAMLパーサに対し、拡張されたプロパティ指定方法を指示する。

-MSDN > WPFの基礎 > WPFのXAML > マークアップ拡張機能とWPF XAML~
http://msdn.microsoft.com/ja-jp/library/ms747254.aspx

***XAMLで定義されたマークアップ拡張 [#ld42b6a9]
以下、XAMLの機能である「XAMLで定義されたマークアップ拡張」を一覧する。~
これらの種類は、中括弧+「x:」プレフィックスの直後の文字列トークンによって識別される。

-XAMLに実装されたマークアップ拡張
|項番|文字列トークン|説明|h
|~|~|例|h
|1|x:Static|静的プロパティ(定数、静的プロパティ、フィールド、列挙値)を参照する。&br;構文:<object property="{x:Static Member=prefix:typeName.staticMemberName}" .../>|
|~|~|<Button&nbsp;&br;&nbsp;&nbsp;&nbsp;&nbsp;Foreground="{x:Static&nbsp;Member=SystemColors.InfoTextBrush}"&br;&nbsp;&nbsp;&nbsp;&nbsp;Background="{x:Static&nbsp;Member=SystemColors.InfoBrush}">&br;&nbsp;&nbsp;Click&nbsp;Here&br;</Button>|
|2|x:Null|CLRオブジェクトのプロパティにnull値を設定する(既定値をnullクリアする場合など)。|
|~|~|<Button&nbsp;x:Name="button1"&nbsp;Background="{x:Null}"&nbsp;Click="button1_Click">&br;&nbsp;&nbsp;Click&nbsp;Here&br;</Button>|
|3|x:Type|CLRクラスの型情報を指定する。|
|~|~|詳しくは、下記、項番4の例を参照のこと。|
|4|x:Array|IEnumerableを持つArrayオブジェクト(配列)を生成する。|
|~|~|<Window.Resources>&br;&nbsp;&nbsp;<x:Array&nbsp;x:Key="List"&br;&nbsp;&nbsp;&nbsp;&nbsp;Type="{x:Type&nbsp;sys:String}">&br;&nbsp;&nbsp;&nbsp;&nbsp;<sys:String>A</sys:String>&br;&nbsp;&nbsp;&nbsp;&nbsp;<sys:String>B</sys:String>&br;&nbsp;&nbsp;&nbsp;&nbsp;<sys:String>C</sys:String>&br;&nbsp;&nbsp;</x:Array>&br;</Window.Resources>&br;<StackPanel>&br;&nbsp;&nbsp;<ListBox&nbsp;ItemsSource="{Binding&nbsp;Source={StaticResource&nbsp;List}}"/>&br;</StackPanel>&br;&br;※&nbsp;先頭で、.NET&nbsp;FrameworkのSystem名前空間のインポートが必要&br;&nbsp;&nbsp;&nbsp;xmlns:sys="clr-namespace:System;assembly=mscorlib"&br;&br;※&nbsp;StaticResourceについては次項で説明する。|

※ x:Arrayは、例外的に中括弧と共に使用しない。

***WPF固有のマークアップ拡張 [#dbf77234]
以下、WPF の機能である「WPF固有のマークアップ拡張」を一覧する。~
こちらは、プロパティ値に「データ バインディング」や、「リソース」への参照を指定できる。

-XAMLに実装されたマークアップ拡張
|項番|文字列トークン|説明|h
|~|~|構文 ※ 「[[プロパティ属性構文>#q550d6b3]]」と「[[プロパティ要素構文>#fa957fd3]]」については、後述する。|h
|1|{Binding&br;・・・|Bindingオブジェクトに「バインディング ターゲット」のプロパティを設定することで、「データ バインディング」を実装する。&br;MSDN > WPFの基礎 > WPFのXAML > WPF XAML拡張機能 > バインディングのマークアップ拡張機能&br;http://msdn.microsoft.com/ja-jp/library/ms750413.aspx|
|~|~|具体例は、「[[データ バインディングの基礎>#bbd76ce0]]」を参照のこと。|
|2|{StaticResource&br;・・・|既に定義されたリソースに対する参照を検索し、任意のXAMLプロパティ属性の値を設定する。|
|~|~|具体例は、「[[リソースとのデータ バインディング>#ac5a7f33]]」を参照のこと。&br;&br;プロパティ属性構文:&br;<object&nbsp;property="{StaticResource&nbsp;key}"&nbsp;.../>&br;&br;なお、「データ&nbsp;バインディング」で使用する場合は、次のようになる。&br;<object&nbsp;property="{Binding&nbsp;Source={StaticResource&nbsp;key}&nbsp;...}"&nbsp;.../>&br;&br;プロパティ要素構文:&br;<object>&br;&nbsp;&nbsp;<object.property>&br;&nbsp;&nbsp;&nbsp;&nbsp;<StaticResource&nbsp;ResourceKey="key"&nbsp;.../>&br;&nbsp;&nbsp;</object.property>&br;</object>|
|3|{DynamicResource&br;・・・|リソースが変化したときに、任意のXAMLプロパティ属性の値を設定する。&br;keyには、x:Key属性によって指定された既存の「リソース」に対応するキーを指定する。|
|~|~|具体例は、「[[リソースとのデータ バインディング>#ac5a7f33]]」を参照のこと。&br;&br;プロパティ属性構文:&br;<object&nbsp;property="{DynamicResource&nbsp;key}"&nbsp;.../>&br;&br;なお、「データ&nbsp;バインディング」で使用する場合は、次のようになる。&br;<object&nbsp;property="{Binding&nbsp;Source={DynamicResource&nbsp;key}&nbsp;...}&nbsp;"&nbsp;.../>&br;&br;プロパティ要素構文:&br;<object>&br;&nbsp;&nbsp;<object.property>&br;&nbsp;&nbsp;&nbsp;&nbsp;<DynamicResource&nbsp;ResourceKey="key"&nbsp;.../>&br;&nbsp;&nbsp;</object.property>&br;</object>|
|4|{RelativeSource&br;・・・|Binding.RelativeSourceを指定する。詳しくは、下記のURLを参照のこと。&br;また、次ページで例を挙げて説明する。&br;&br;MSDN > WPFの基礎 > WPFのXAML > WPF XAML拡張機能 > RelativeSourceのマークアップ拡張機能&br;http://msdn.microsoft.com/ja-jp/library/ms743599.aspx|
|~|~|具体例は、次ページを参照のこと。&br;&br;プロパティ属性構文:&br;<Binding&nbsp;RelativeSource="{RelativeSource&nbsp;modeEnumValue}"&nbsp;.../>&br;&br;なお、「データ&nbsp;バインディング」で使用する場合は、次のようになる。&br;<object&nbsp;property="{Binding&nbsp;RelativeSource={RelativeSource&nbsp;modeEnumValue}&nbsp;...}"&nbsp;.../>&br;&br;プロパティ要素構文:&br;<Binding>&br;&nbsp;&nbsp;<Binding.RelativeSource>&br;&nbsp;&nbsp;&nbsp;&nbsp;<RelativeSource&nbsp;Mode="modeEnumValue"/>&br;&nbsp;&nbsp;</Binding.RelativeSource>&br;</Binding>&br;&nbsp;OR&nbsp;&br;<Binding>&br;&nbsp;&nbsp;<Binding.RelativeSource>&br;&nbsp;&nbsp;&nbsp;&nbsp;<Relative&br;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mode="FindAncestor"&br;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AncestorType="{x:Type&nbsp;typeName}"&br;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AncestorLevel="intLevel"/>&br;&nbsp;&nbsp;</Binding.RelativeSource>&br;</Binding>|
|5|{TemplateBinding&br;・・・|親コントロールに適用したプロパティ値を「テンプレート」に反映させる。&br;MSDN > WPFの基礎 > WPFのXAML > WPF XAML拡張機能 > TemplateBindingのマークアップ拡張機能&br;http://msdn.microsoft.com/ja-jp/library/ms742882.aspx|
|~|~|具体例は、「[[テンプレート>#bb58b780]]」を参照のこと。&br;&br;プロパティ属性構文:&br;<object property="{TemplateBinding TargetProperty }" .../>|
|6|{ThemeDictionary&br;・・・|カスタム コントロールの作成者やサードパーティ製のUIコンポーネントの、&br;コントロールの「スタイル」をアプリケーションの「リソース」から読み込む。&br;&br;MSDN > WPFの基礎 > WPFのXAML > WPF XAML拡張機能 > ThemeDictionaryのマークアップ拡張機能&br;http://msdn.microsoft.com/ja-jp/library/ms752067.aspx|
|~|~|-|

※ keyには、x:Keyディレクティブによって指定された既存のリソースに対応するキーを指定する。

***RelativeSourceの例 [#b35e6e76]
以下、RelativeSourceの「マークアップ拡張」について、XAMLサンプルを用いて説明する。~
なお、Button.Template以下の要素(→ 「[[テンプレート>#bb58b780]]」)については、「[[テンプレート>#bb58b780]]」を参照のこと。

-RelativeSourceの例
 <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>

-レンダリング結果
#ref(RenderingResult.png,left,nowrap,レンダリング結果)

-(1)では、TextBlock要素自身のFontFamilyプロパティを取得して、自身のTextプロパティに設定している。
-(2)では、親要素(AncestorType 属性に指定されているStackPanel型)を検索し、Orientationプロパティを取得して、自身のTextプロパティに設定している。
-(3)では、TemplatedParent 属性により、テンプレートを適用しているControlTemplate(ここでは、ControlTemplateであるButton要素)の~
Contentプロパティを取得し、ContentPresenterクラスのContentプロパティに設定している。

-MSDN > WPFの基礎 > WPFのXAML > WPF XAML拡張機能~
http://msdn.microsoft.com/ja-jp/library/ms747180.aspx

*プロパティの設定方法 [#ra4d77a1]
プロパティの設定方法として、
-プロパティ属性構文:~
要素の属性にテキストを使用して設定する。
-プロパティ要素構文:~
要素のinnerText・innerXMLを使用してプロパティを設定する。

の2つの構文について説明する。

以下、TextBox要素に対して、同等の属性を設定する~
「[[プロパティ属性構文>#q550d6b3]]」と「[[プロパティ要素構文>#fa957fd3]]」の例を示す。

**プロパティ属性構文 [#tb0bd2e6]
要素の属性にテキストを使用してプロパティを設定する方法

-プロパティ属性構文の例
 <TextBox 
    Width = "100"
    FontSize = "30"
    Text = "text1"
    Background = "White"
    Foreground = "Blue" />

**プロパティ要素構文 [#s389a559]
要素の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>

なお、子要素のコレクションを設定する「[[プロパティ要素構文>#fa957fd3]]」である
-Panel.Childrenプロパティ
-ItemsControl.Itemsプロパティ

などは、暗黙的に使用されるため明記が不要のものもある。

**型コンバータ [#r36d6abd]
XAMLパーサは、XAMLの「[[プロパティ属性構文>#q550d6b3]]」として指定された各属性テキストを、~
プリミティブ型に変換できるリテラル文字列として解釈するか、「型コンバータ」を使用してオブジェクトに変換する。

なお、「型コンバータ」(と、そのベース クラスであるTypeConverterクラス)は、~
.NETのコンポーネントとコントロールのデザイン時・実行時の動作を実装する一般的なクラスであり、WPF独自のクラスではない。~
しかし、XAMLの「[[プロパティ属性構文>#q550d6b3]]」からのCLRプロパティ設定を多用するWPF / Silverlight開発では、その存在を認識しておいたほうが良い。

XAMLパーサは通常、プロパティの型(CLRクラス)にTypeConverterAttribute属性 が付与されているかを調べる。~
付与されている場合は、この属性値に基づいた「型コンバータ」を使って、TypeConverter.ConvertFromメソッド により文字列をプロパティ値に変換する。

以下は、ユーザ コントロールに、MyPointというカスタムの型を取るCLRプロパティを実装しXAMLに公開、~
XAMLの「[[プロパティ属性構文>#q550d6b3]]」として指定された各属性テキストを、カスタムの型に変換する「型コンバータ」を実装した例である。

***カスタム型 [#p2ae99f0]
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; }
   }
 }

***型コンバータ [#k0c10e95]
 /// <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);
   }
 }

***ユーザ コントロール [#gc3459c6]
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; }
   }
 
 ・・・

***型コンバータの使用例 [#gc5dd259]
上記のユーザ コントロールのカスタムの型を取るCLRプロパティを、以下のようにXAMLの「[[プロパティ属性構文>#q550d6b3]]」として指定された各属性テキストから初期化できる。

 <uc:UserControl1 x:Name="userControl1" MyLocation="10,20"/>

ただし、(当然ながら、)文字列からの変換をサポートしているだけで、すべてのプロパティ値をサポートすることはできない。~
文字列で表現できないプロパティ値は、「[[プロパティ属性構文>#q550d6b3]]」ではなく「[[プロパティ要素構文>#fa957fd3]]」として記述する方法を取る。

-MSDN > WPFの基礎 > WPFのXAML > TypeConverters及びXAML~
http://msdn.microsoft.com/ja-jp/library/aa970913.aspx

*コンテンツ構文 [#m4c088a5]
「コンテンツ構文」とは、Contentプロパティ(またはItemsコレクション プロパティ)に要素を設定する構文である。~
ContentPropertyAttributeを付けることで、通常、属性に指定されるContentプロパティを、要素のinnerText・innerXMLとして記述できるようになる。

-MSDN > .NET Frameworkクラス ライブラリ > System.Windows.Markup.ContentPropertyAttributeクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.markup.contentpropertyattribute.aspx
--[ContentPropertyAttribute("Content")]→ Contentプロパティ
--[ContentPropertyAttribute("Items")]→ Itemsコレクション プロパティ

-コンテンツ構文
--プロパティ属性構文
 <Button Content="Click Here" />
--プロパティ要素構文
 <Button>Click Here</Button>

なお、WindowsフォームやWebフォーム(HTML)などで、~
UIコントロールの表示のカスタマイズをするには、~
UIコントロールの「スタイル」属性の指定による方法のみサポートされていた。

これに対し、WPFのUIコントロールは「スタイル」属性の指定による方法だけでなく、~
Contentプロパティ(またはItemsコレクション プロパティ)に任意の型の子要素を設定することができるため、~
コントロールの「外観」を自由に変更でき、柔軟性が非常に高くなっている。

-補足:Windowsフォームの外観の変更
--Windowsフォームの「外観」を変更するには、コントロールを自前で描画する「オーナー描画」と呼ばれる方法が用意されていた。~
しかしながら、「オーナー描画」はグラフィックス メソッドなどを使用して、すべての描画を独自に行わなければならないため、コントロールに対する深い知識と多量のコードが必要であった。

--関連資料
---[[.NETコントロールのカスタマイズ方法]]

**Contentプロパティ [#gc84bde8]
WPFのContentControlは、Contentプロパティに任意の型の子要素を設定することができるため、コントロールの「外観」を自由に変更できる。

***文字列のコンテンツ要素を格納 [#m12672f2]
#ref(ContentString.png,left,nowrap,レンダリング結果)

ContentControlのButtonコントロールを例にしてContentプロパティへ要素を設定する例を示す。

-プロパティ属性構文:
 <Button Width="200" Height="200" Content="ボタン"/>
-プロパティ要素構文:
 <Button Width="200" Height="200">ボタン</Button>

***イメージのコンテンツ要素を格納 [#faf81a9f]
#ref(ContentImage.png,left,nowrap,レンダリング結果)

Contentプロパティには、Imageオブジェクトなどの任意の型の要素も設定できる。

 <Button Width="200" Height="200">
   <Button.Content>
     <Image Source=".\Blue hills.jpg"/>
   </Button.Content>
 </Button>

***パネルに纏めた複数のコンテンツ要素を格納 [#a73fa28e]
#ref(ContentStringAndImage.png,left,nowrap,レンダリング結果)

-2つ以上の要素を設定したい場合は、パネル要素を使用する。
 <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>

-なお、<Object.Content>タグは省略することもできる。
 <Button Width="200" Height="200">
   <StackPanel Orientation="Vertical">
     <Image Source=".\Blue hills.jpg" Margin="5" />
     <TextBlock Text="ボタン" HorizontalAlignment="Center" Margin="5"/>
   </StackPanel>
 </Button>

**Itemsプロパティ [#v7960713]
WPFのItemsControlは、Itemsコレクション プロパティに任意の型の子要素を設定することができるため、コントロールの「外観」を自由に変更できる。

***複数のパネルに纏めた複数のコンテンツ要素を格納 [#w0ea6ec9]
ItemsControlのItemsコレクション プロパティへは、複数のコンテンツを追加できる。~
以下、ListBoxコントロールを例にしてItemsコレクション プロパティへ子要素の設定する例を示す。

#ref(ItemsControl.png,left,nowrap,レンダリング結果)

-複数のパネルに纏めた複数のコンテンツ要素を格納
 <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>

-Itemsコレクション プロパティに子要素を設定する場合は、~
innerText・innerXMLを使用する「[[プロパティ要素構文>#fa957fd3]]」を使用する。
-また、この際に<Object.Items>タグは省略することもできる。

-ちなみに、上記を「データ バインディング」で実装することもできる。~
これについては、「[[データ バインディングの基礎>#bbd76ce0]]」を参照のこと。

*リソース [#p50dd8ac]
ここでは、

-「リソース」の定義方法と、

-前述の各「マークアップ拡張」を使用し、~
プロパティ値に「リソース」への参照を指定する方法

について説明する。

※「リソース」の「データ バインディング」については、~
「[[リソースとのデータ バインディング>#ac5a7f33]]」を参照のこと。

-参考
--MSDN > WPFの基礎 > リソース~
http://msdn.microsoft.com/ja-jp/library/ms742538.aspx

**リソースの定義 [#g7e2fd50]
「リソース」とは、ResourceDictionary 型のオブジェクトであり、
-ApplicationオブジェクトのResources プロパティ
-各UI要素(FrameworkElement or FrameworkContentElement)のResources プロパティ

に「プロパティ要素構文」を使用して定義できる。

-MSDN > .NET Frameworkクラス ライブラリ
-- > System.Windows.ResourceDictionaryクラス~
http://msdn.microsoft.com/ja-jp/library/system.windows.resourcedictionary.aspx
-- > System.Windows.Application.Resourcesプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.application.resources.aspx
-- > System.Windows.FrameworkElement.Resourcesプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.frameworkelement.resources.aspx
-- > System.Windows.FrameworkContentElement.Resourcesプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.frameworkcontentelement.resources.aspx

このため、任意のUI要素に定義可能であるが、~
通常はルート要素(Window or Page)上に定義する。~

また、「リソース」は、定義場所により以下のような呼称・特徴がある。

***リソースの定義場所 [#qe6a5b64]

-アプリケーション リソース~
ApplicationオブジェクトのResourcesプロパティに定義された「リソース」を~
「アプリケーション リソース」と呼び、全体から(つまりどこからでも)参照できるという特徴を持っている。

-ウィンドウ ページ リソース~
Window・PageオブジェクトのResourcesプロパティに定義された「リソース」を~
「アプリケーション リソース」と呼び、そのWindow・Pageと、その子要素から参照できるという特徴を持っている。

-イミディエイト リソース~
各UI要素(FrameworkElement or FrameworkContentElement)の~
Resourcesプロパティに定義された「リソース」を「イミディエイト・リソース」と呼び、~
「リソース」を定義した要素と、その子要素から参照できるという特徴を持っている。

***リソースの定義例 [#sedc736a]
-「リソース」には、前述のx:Key ディレクティブを使用して一意のキーを持たせて定義する必要がある。~
 <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:TypeArgumentsのディレクティブを使用して、~
ObservableCollection<T>コレクション クラスなどのジェネリック型のコンストラクタに渡す必要があるが、~
これは、XAML2009 からのサポートとなる。

***リソースの使用方法 [#r6badd32]
「リソース」を定義したら、各種「マークアップ拡張」を使用して、~
プロパティ値に「データ バインディング」や、「リソース」への参照を指定できる。

この時、参照する側からx:Key ディレクティブを使用して割り当てたキーを「リソース」検索のキーとして指定できる。

なお、「スタイル」や「テンプレート」などは、キーを定義せず、TargetType 属性のみ使用して、~
指定の型のオブジェクトに「スタイル」や「テンプレート」を適用することもできる。~
これについては、「[[スタイルとテンプレート>#q002601b]]」を参照のこと。

-MSDN > .NET Frameworkクラス ライブラリ
-- > System.Windows.Style.TargetType プロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.style.targettype.aspx
-- > System.Windows.Controls.ControlTemplate.TargetTypeプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.controltemplate.targettype.aspx

**リソースの定義と参照 [#wd960230]
以下、「リソース」の定義と、プロパティ値に「リソース」への参照を指定する例を示す。

***StaticResource参照の例 [#ybb9b94a]
StaticResource参照では、
-コンパイル時に「リソース」検索が行われ、各「リソース」に指定されたキーが存在するかどうかが確認される。
-「リソース」検索により、「リソース」が発見できなかった場合は、コンパイル時にエラーとなる。

以下は、StaticResourceの定義と参照例。

-StaticResourceの定義と参照例(1)
--以下は、「マークアップ拡張」を使用して、「プロパティ属性構文」でStaticResource参照した例である。
--また、属性名を省略すると自動的にコンストラクタに渡される動作を利用して、~
ResourceKey属性に指定の値を渡す旨を指示する「ResourceKey=」という記述を省略することができる。

>
 <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>

#ref(StaticResource.png,left,nowrap,StaticResourceの定義と参照例(1))


-StaticResourceの定義と参照例(2)~
以下は、一般的ではないが「プロパティ要素構文」を使用してStaticResource参照した例である。~
なお、WPFのみ、StaticResource参照を「プロパティ要素構文」で記述可能である。

>
 <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参照の例 [#h04a05da]
-DynamicResource参照では、アプリケーションの起動時に、~
後で「リソース」検索を行う際に使用する一時的な式が作成され、~
アプリケーションの実行後、「リソース」が必要になった際に都度、「リソース」検索が行われる。

-このためDynamicResource参照は、
--主に「リソース」の値が変更される場合、StaticResource参照に代替して使用する。
--「リソース」検索により、「リソース」が発見できなかった場合は、デフォルト値が設定される。

-なお、DynamicResource参照は、WPFでのみ利用可能で、「Silverlight」では利用不可である。

以下は、DynamicResourceの定義と参照例。

-以下は、リソースがアプリケーション外部から変更される場合の例~
以下は、デスクトップ画面のテーマの変更(Windows XP → Windowsクラシック)を反映する例である。~

>
 <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>

#ref(DynamicResource.png,left,nowrap,DynamicResourceの定義と参照例(リソースがアプリケーション外部から変更される場合))

-以下は、リソースがアプリケーション内部から変更される場合の例~
以下は、アプリケーションからの「リソース」の動的な変更を反映する例である。~
なお、「リソース」の動的な変更は、FrameworkElement.Resourcesプロパティで変更できる。
--XAML
 <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;
 }

#ref(DynamicResource2.png,left,nowrap,DynamicResourceの定義と参照例(リソースがアプリケーション内部から変更される場合)

***StaticResource参照 + ディクショナリ ファイルの例 [#k8074527]
ResourceDictionaryは、「ディクショナリ ファイル」に定義することもできる。

「ディクショナリ ファイル」を追加する際は、
+プロジェクト ファイルを右クリックし、
+[追加] → [リソース ディクショナリ]を選択するか、~
[追加] → [新しい項目]を選択し、表示されるテンプレートから[リソース ディクショナリ(WPF)]を選択する。

#ref(AddDictionary.png,left,nowrap,ディクショナリ ファイルの追加)

-前述のStaticResource参照の例を、~
「ディクショナリ ファイル」を使用するように書き直した例を以下に示す。
 <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>

>
#ref(StaticResourceAndDictionary.png,left,nowrap,StaticResource参照 + ディクショナリ ファイルの使用例)
''StaticResource参照 + ディクショナリ ファイルの使用例''

***DynamicResource参照 + ディクショナリ ファイルの例 [#z0de9556]
-DynamicResource参照とResourceDictionaryを組み合わせ、
-ResourceDictionaryを、Application.LoadComponentで動的にロード、
-Application.Current.Resourcesに設定することにより、
-「スタイル」(スキン )などの設定をアプリケーションから動的に変更することが可能である。

以下の、その例を示す。

-Dictionary
--Dictionary1.xaml
 <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>
--Dictionary2.xaml
 <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>

-XAML
 <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;
   }
 }

>
#ref(DynamicResourceAndDictionary.png,left,nowrap,DynamicResource参照 + ディクショナリ ファイルの使用例)

''DynamicResource参照 + ディクショナリ ファイルの使用例''

*データ バインディング [#w4afa32c]
様々なソースと「データ バインディング」するサンプルを示す。

なお、サンプルのXAMLソースを読むためには、以下の、~
Bindingプロパティの設定方法を理解しておく必要がある。

''Bindingプロパティの設定方法''
|項番|プロパティ|説明|h
|1|Mode|OneTime、OneWay、TwoWay のいずれかの「バインディング モード」を指定する。|
|2|Source|「バインディング ソース」を指定する。「バインディング ソース」は、&br;「[[リソース>#ea30adb6]]」に定義し、[[StaticResourceの「マークアップ拡張」>#f8bba188]]を使用して「データ バインディング」するか、&br;FrameworkElement.DataContextから、「データ バインディング」する。|
|3|ElementName|UI要素名を使用して「バインディング ソース」を指定する。|
|4|RelativeSource|「バインディング ターゲット」からの相対位置で「バインディング ソース」を指定する。&br;※ Self、TemplatedParent、AncestorType、AncestorLevel属性などを使用して指定する。|
|5|Path|「バインディング ソース」のプロパティ名を指定する(名前空間のフルパスで指定可)。&br;なお、インデクサなどの指定も可能である。詳細は、以下のURLを参照のこと。|
|6|XPath|「バインディング ソース」として、XMLデータソースのXML DOMへのパスを表す文字列を指定する。|
|7|TargetNullValue|ソース値が null のときに返される値を指定する。|
|8|Converter|「[[値コンバータ>WPFのアーキテクチャ#nf7e2b6a]]」を指定する。&br;「[[値コンバータ>WPFのアーキテクチャ#nf7e2b6a]]」は、インスタンス化が可能であり、ResourceDictionaryに配置できる。&br;「[[値コンバータ>WPFのアーキテクチャ#nf7e2b6a]]」は「[[StaticResource>#ea30adb6]]」に定義し[[StaticResourceの「マークアップ拡張」>#f8bba188]]を使用して参照するようにする。|
|9|ConverterCulture|「[[値コンバータ>WPFのアーキテクチャ#nf7e2b6a]]」で使用するカルチャを指定する。|
|10|ConverterParameter|「[[値コンバータ>WPFのアーキテクチャ#nf7e2b6a]]」の変換ロジックで使用するパラメタを指定する。|

-MSDN > ・・・ > バインディングのマークアップ拡張機能~
http://msdn.microsoft.com/ja-jp/library/ms750413.aspx
--MSDN > ・・・ > PropertyPathのXAML構文~
http://msdn.microsoft.com/ja-jp/library/ms742451.aspx
--MSDN > ・・・ > 方法:XMLDataProviderとXPathクエリを試用してXMLデータにバインドする~
http://msdn.microsoft.com/ja-jp/library/ms749287.aspx

**データ バインディングの基礎 [#h0ae3316]
以下、「[[WPFのアーキテクチャ - データ バインディング>WPFのアーキテクチャ#dac6f2bf]]」に対応するサンプルを示す。

***コードビハインドからのデータ バインディング(モード:OneWay) [#o2aaa11e]
-モード:OneWayの「データ バインディング」を行う。
-「データ バインディング」の基本的な動作を理解するために、
--Bindingオブジェクトをコード ビハインドで自作し、
--以下の2つのオブジェクトを結びつける。
---「バインディング ソース」
---「バインディング ターゲット」

-XAML
 <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; }
 }

***コードビハインドからのDataContextを使用したデータ バインディング(モード:OneWay) [#mb48f656]

上記の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);
 }

-BindingオブジェクトをXAMLで実装する(プロパティ要素構文)~
更に、XAMLのマークアップ機能を使用して、Bindingオブジェクトの生成処理・設定処理をXAML側に移動することで、~
上記のXAMLとMainPanel_Loadedメソッドのコードを一部編集し、コード ビハインドのコード量を削減できる。

--XAML
 <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 };
 }

-BindingオブジェクトをXAMLで実装する(プロパティ属性構文)~
一般的には、「データ バインディング」を実装する場合、~
XAML側の記述は「バインディングのマークアップ拡張」により~
「プロパティ属性構文」化して実装する方法を採る。
--更に、上記のXAMLを「バインディングのマークアップ拡張」を使用して、~
「プロパティ属性構文」化して実装すると次のようになる。
--また、属性名を省略すると自動的にコンストラクタに渡される動作を利用して、~
(Path属性に指定の値を渡す旨を指示する)「Path=」という記述を省略することができる。

>>
 <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 & OneWayToSource)~
下記は、モード:OneWay & OneWayToSourceを併用した「データ バインディング」によるBMI(肥満度)の自動計算アプリケーションの例である。~
この例では、「バインディング ソース」のプロパティ値の変更を、自動的に「バインディング ターゲット」に反映できる。~
なお、この際、「バインディング ソース」は、INotifyPropertyChangedインターフェイスを実装して、BMI(肥満度)プロパティの変更通知処理を実装する必要がある。

--XAML
 <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
 }


**リソースとのデータ バインディング [#eb81566f]

*レイアウト [#lc8aa2dd]
**レイアウトのプロパティ [#ad27e006]
**パネルの種類と使い方 [#t2926641]

*スタイルとテンプレート [#j0c577be]
**スタイル [#v30d5ab6]
**テンプレート [#o64ea160]

*トリガ [#x73e9a3a]
**プロパティ トリガ [#z60358ba]
**データ トリガ [#af3def31]
**イベント トリガ [#p908262c]

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS