マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

基本的なXAMLの書き方。

名前空間

XAMLにおける各種の名前空間の宣言は、xmlns属性を使用したXML名前空間にて行う。
ここでは、以下の既定の名前空間の宣言を例にとって説明する。

WPF名前空間

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名前空間

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

CLR名前空間

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

(1)

Infragistics社製のNetAdvantage?など、

XmlnsDefinition?アセンブリ属性でURIとCLR名前空間のマップが指定された
サードパーティ製のUIコンポーネントをD&DでVSデザイナから追加した場合、

上記の例のように自動的にXML名前空間の宣言が追加される。

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

(2)

この他に、URIとしてCLR名前空間とアセンブリを直接指定する方法もある。

参考

言語機能

XAMLの言語機能である

について説明する。

ディレクティブ

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

項番ディレクティブ説明
1x:ClassXAML上から分離クラス(コードビハインド)のクラス名を定義する。
<Window x:Class="WpfApplication1.Window1"
2x:Subclassパーシャル クラスをサポートしない言語で使用する。通常は利用しない。
3x: ClassModifier?クラスのアクセスレベルを変更する。通常は利用しない。
4x:CodeXAML上にインラインコードを実装する場合に使用する。通常は利用しない。
<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>
5x:FieldModifier?プロパティのアクセスレベルを変更する。通常は利用しない。
6x:KeyXAMLで定義された各種「リソース」を識別する。下記は、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>
7x:NameXAMLで生成したCLRオブジェクトに名前を付与する。Name属性と差異は無い。
<Button x:Name="button1">
   Click Here
</Button>
8x:Shared静的なリソースを、取得の度に生成する場合に使用する。通常は利用しない。
※ true : 静的(全てのインスタンスは同じ)
   false : 動的(取得の度に生成する)
   既定値 : true
9x: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?>
10x:Uidローカライゼーションのプロセスとツールによって使用される一意識別子を指定する 。
11xml: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の機能である「XAMLで定義されたマークアップ拡張」を一覧する。
これらの種類は、中括弧+「x:」プレフィックスの直後の文字列トークンによって識別される。

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

WPF固有のマークアップ拡張

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

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

マークアップ拡張の例

バインディングのマークアップ拡張の例

こちら

TemplateBinding?の例

こちら

RelativeSource?の例

こちら

プロパティの設定方法

プロパティの設定方法として、

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

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

プロパティ属性構文

要素の属性にテキストを使用してプロパティを設定する方法

プロパティ要素構文

要素のinnerText・innerXMLを使用してプロパティを設定する方法

なお、子要素のコレクションを設定する「プロパティ要素構文」である

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

型コンバータ

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プロパティ)に要素を設定する構文である。

Contentプロパティ

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

文字列のコンテンツ要素を格納

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

イメージのコンテンツ要素を格納

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

パネルに纏めて格納した複数のコンテンツ要素

Itemsプロパティ

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

複数のパネルに纏めて格納した複数のコンテンツ要素

ItemsControl?のItemsプロパティへは、複数のコンテンツを追加できる。
以下、ListBox?コントロールを例にしてItemsプロパティへ子要素の設定する例を示す。

リソース

ここでは、

について説明する。

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

リソースの定義

「リソース」とは、ResourceDictionary? 型のオブジェクトであり、

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

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

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

リソースの定義場所

リソースの定義例

リソースの使用方法

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

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

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

リソースの定義と参照

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

StaticResource?参照の例

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>

DynamicResource?参照の例

以下は、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>
DynamicResourceの定義と参照例(リソースがアプリケーション外部から変更される場合)
DynamicResourceの定義と参照例(リソースがアプリケーション内部から変更される場合

StaticResource?参照 + ディクショナリ ファイルの例

ResourceDictionary?は、「ディクショナリ ファイル」に定義することもできる。

「ディクショナリ ファイル」を追加する際は、

  1. プロジェクト ファイルを右クリックし、
  2. [追加] → [リソース ディクショナリ]を選択するか、
    [追加] → [新しい項目]を選択し、表示されるテンプレートから[リソース ディクショナリ(WPF)]を選択する。
ディクショナリ ファイルの追加
StaticResource参照 + ディクショナリ ファイルの使用例

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

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

以下の、その例を示す。

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

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

データ バインディング

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

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

Bindingプロパティの設定方法

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

データ バインディングの基礎

以下、「WPFのアーキテクチャ - データ バインディング」に対応するサンプルを示す。

コードビハインドからのデータ バインディング(モード:OneWay?

コードビハインドからのDataContext?を使用したデータ バインディング(モード:OneWay?

上記のMainPanel_Loadedメソッドのコードを一部編集し、MainPanel?StackPanel?)の
FrameworkElement?.DataContext?プロパティに「バインディング ソース」を設定することで、
Bindingオブジェクトへの「バインディング ソース」の指定が不要になる。

BindingオブジェクトをXAMLで実装する(プロパティ要素構文

Bindingオブジェクトをバインディングのマークアップ拡張で実装する(プロパティ属性構文

変更通知の追加(モード:OneWay? or OneWayToSource?

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

値コンバータを使用したデータ バインディング(モード:OneWay? or OneWayToSource?

続いて、上記処理に、BMI(肥満度)プロパティが

変更する処理を追加する。

これには別途、背景色プロパティを定義することで実現することも可能であるが、
ここでは、前述のIValueConverter?インターフェイスを実装した「値コンバータ」を実装することでこれを実現する。
値の変換処理は、「値コンバータ」のConvertメソッドに実装する。

INotifyPropertyChanged?の変更通知を「依存関係プロパティ」で代替

なお、変更通知は、INotifyPropertyChanged?インターフェイスの実装ではなく、「依存関係プロパティ」でも代替できる。
上記の例のBMI(肥満度)プロパティを「依存関係プロパティ」として、以下のように書き直し、動作を確認する。

BMI(肥満度)プロパティが変更されると、UI要素(TextBlock?)に変更が反映されることを確認できる。
このように、「依存関係プロパティ」は既定で変更通知をサポートしている。

双方向のデータ バインディング(モード:TwoWay?

以下の例では、モード:TwoWay?の「データ バインディング」を行うため、
2つのUI要素、TextBox?とSliderを双方向接続した例である。

なお前述のようにUI要素の表示に関するプロパティは、
基本的に「依存関係プロパティ」として定義されており、
既定で変更通知をサポートしている。このため、既定で双方向接続が可能である。

なお、「バインディング ソース」をUI要素に接続する場合は、ElementName?属性を使用すると良い。

値コンバータを使用したデータ バインディング(モード:TwoWay?

双方向の値の変換に対応した「値コンバータ」は、
Convert、ConvertBack?メソッドの双方を実装する必要がある。

ItemsSource?へのデータ バインディング

ItemsControl?から派生した要素のItemsSource?属性にコレクションを「データ バインディング」する場合、対象オブジェクトは反復処理をサポートしている必要がある。

インデクサによるデータ バインディング

インデクサについても、Path属性に角括弧を指定することで接続可能である。

これらを応用すると、

インデクサを持つオブジェクトの配列(反復処理をサポート)
をデータ バインディングすることも可能であることが分かる。

ビジネス・アプリケーションでは、DataGrid?DataTable?をデータ バインディングする際に、
DataGrid?の列へDataTable?の列をマッピングするようなケースでよく利用します。

リソースとのデータ バインディング

リソース」参照を「バインディングのマークアップ拡張」でも使用することができる。

StaticResource?を使用したデータ バインディング

DynamicResource?を使用したデータ バインディング

動的な「リソース」を使用した「データ バインディング」はサポートされない。
以下、「{Binding Source={DynamicResource?」をテストした際のエラーメッセージである。

型 'Binding' の 'Source' プロパティで 'DynamicResourceExtension' を設定することはできません。'DynamicResourceExtension' は、DependencyObject の DependencyProperty でのみ設定できます。

レイアウト

ココでは、レイアウト方法として、

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

レイアウトのプロパティ

パネルの種類と使い方

WPFでは、パネルを使用した「レイアウト」が可能である。

キャンバス パネル

ドック パネル

スタック パネル

折り返しパネル

(均一)グリッド パネル

グリッド パネル

スタイルとテンプレート

ココでは、「外観」に関する設定を行う「スタイル」と「テンプレート」について説明する。

スタイル

スタイルの基本

「スタイル」は、UI要素の「依存関係プロパティ」の一括管理機能を持ち、これを使用して「外観」に統一性を持たせるための機能である。
「スタイル」は、Style型のオブジェクトであり、各UI要素(FrameworkElement? or FrameworkContentElement?)のStyleプロパティに指定可能である。

スタイルの継承

(Silverlight 2のStyleクラスにはBasedOn?プロパティが存在しなかったが、Silverlight 3で追加されている)

外部ディクショナリ ファイル化

実行時スタイル

の方法を、「スタイル」でも応用可能である。

テンプレート

テンプレートの基本

任意の型の子要素を設定することができる。

「テンプレート」値を反映させる方法

また、親コントロールに適用した、「テンプレート」の値を
Contentプロパティ(またはItemsプロパティ)を含む
プロパティ値に反映させるにめには、下記の3通りの方法を使用できる。

コントロールと「テンプレート」内の各要素の関係

以上を纏めた、コントロールと「テンプレート」内の各要素の関係は、次のようになる。

同じ要領で、コントロールによってはヘッダやセル専用の「テンプレート」プロパティが存在し、「外観」のカスタマイズを行うことができる。

ContentControl?のテンプレート(ControlTemplate?)の例

トリガ

プロパティ トリガ

データ トリガ

イベント トリガ


Tags: :.NET開発, :UIサブシステム, :WPF/Silverlight, XAML


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