FANDOM


XAMLはXMLマークアップを使用してWindowsのフォームをデザインするエンジンです。
WPFではXAMLによるデザインを実装しています。

XAMLの記述方法 編集

XAMLは通常のXMLと同じように、実装が定義されたタグを使って要素を構造化していきます。 タグには属性値を設定することもでき、タグに対しての様々なパラメータの設定が可能です。

1つのタグから構成される要素をノードと呼び、ノードを階層化していくことができます。 階層化されたノード同士を親ノード・子ノードと呼びます。タグによっては子ノードを持つことができないものもあります。

XAMLのタグはすべてがWPFで実装されたクラスが存在しています。
例えば、ButtonタグはWPFではSystem.Windows.Controls.Buttonクラスがその実態です。XAMLでタグを扱う場合にどのようなタグでありどのような属性を持つかは実装コードを調べればわかるようになっています。


XAMLでの属性値 編集

XAMLのタグはすべてWPFで実態が実装されています。
タグに設定可能な属性はプロパティとして実装されます。

  1. <Button Text="実行ボタン" />

このようなButtonタグはSystem.Windows.Controls.Buttonクラスが実態です。
そして、このタグで使用しているText属性はButtonクラスのTextプロパティとして実装済みです。Textプロパティはstring型のプロパティです。

XMLでは見慣れないXAML独自の表記方法として、属性をノードとして扱う方法があります。
たとえば上記のText属性は次のようにButtonタグの子ノードを使って記述することもできます。

  1. <Button>
  2. 	<Button.Text>
  3. 		実行ボタン
  4. 	</Button.Text>
  5. </Button>

このような子ノードをプロパティ要素と呼びます。

ただし、すべての属性はプロパティ要素をつかって記述が可能ですがその逆は必ずしも一致しません。

  1. <Border>
  2. 	<Border.Child>
  3. 		<TextBox Text="サンプルテキスト" />
  4. 	</Border.Child>
  5. </Border>

Border.ChildはUIElement型ですがUIElementのインスタンスをXAML上で作成する場合は、上記のようにBorder.Childというプロパティ要素の子ノードに記述を行います。

省略可能な属性値 編集

オブジェクト要素には1つだけ記述を省略して良いプロパティ要素が定義されているものがあり、このようなプロパティ要素をコンテンツプロパティと呼びます。

BorderタグはBorder.Childプロパティがコンテンツプロパティに設定してあるため、次のように記述することが可能です。

<Border>
	<TextBox Text="サンプルテキスト" />
</Border>


テキストコンテンツ 編集

XMLのTEXT部をそのままプロパティとして設定するように定義されているプロパティがあります。

Buttonタグはテキストコンテンツに文字列がある場合、Button.Textプロパティに値が設定されます。

<Button>実行ボタン</Button>

マークアップ拡張書式 編集

マークアップ拡張書式の種類
拡張名 用途 説明
Binding データバインディング プロパティ要素とのバインディングを構築します。
MultiBinding データバインディング 複数のプロパティ要素とのバインディングを構築します。
PriorityBinding データバインディング
TemplateBinding データバインディング Templateを記述する際にテンプレート内でバインディングを使用する際に使用します。
DynamicResource リソース
StaticResource リソース

スキーム 編集

XAMLはXMLによる記述を行うため、XAML内で使用するスキームを宣言する必要があります。

宣言内容 プリフィックス 名前空間 備考
XAML全般の名前空間 xmlns http://schemas.microsoft.com/winfx/2006/xaml/presentation XAMLに使用するオブジェクト要素が定義されたスキーム。
XAML拡張 xmlns:x http://schemas.microsoft.com/winfx/2006/xaml XAML特有の拡張機能を呼び出すための定義。

CLR名前空間の参照用スキーム 編集

自分でコントロールを作成したものをXAMLから参照する場合にもスキームが必要となります。
ソースからスキームを作成しそれを参照する方法もありますが、作成したコントロールがCLR名前空間上のものならばXAMLの拡張機能を使って簡単に参照できます。

<Window xmlns:dn="clr-namespace:My.Package.Controls;assembly=MyPackage">
</Window>

キーワード「clr-namespace」を使って参照したいパッケージ名を記述します。
もし参照先のパッケージが別のアセンブリに属している場合は、assemblyプロパティにアセンブリ名を記述します。(参照元と参照先が同じアセンブリ内ならば不要)

.NET Frameworksのよく使われるパッケージを参照するためのスキーム
記述文章 説明・用途
clr-namespace:System;assembly=mscorlib Int16やDecimalなどの特殊な型。
clr-namespace:System.Collections;assembly=mscorlib コレクション(List / Arrayなど)

リソース 編集

リソースは再利用可能なオブジェクトをXAML内で共有するための定義です。

  1. <Window x:Class="WpfApplication1.MainWindow"
  2.   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.   Title="MainWindow" Height="100" Width="200">
  5.  
  6.   <Window.Resources>
  7.     <SolidColorBrush x:Key="MyBrush" Color="Blue"/>
  8.   </Window.Resources>
  9.  
  10.   <StackPanel>
  11.     <Button Content="Button 1"
  12.       Background="{StaticResource MyBrush}"/>
  13.     <Button Content="Button 2"
  14.       Background="{StaticResource MyBrush}"/>
  15.   </StackPanel>
  16. </Window>

リソースの定義 編集

定義したリソースにもスコープの概念があります。

<Window x:Class="WpfApplication1.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="MainWindow" Height="100" Width="200">

  <Window.Resources>
    <SolidColorBrush x:Key="MyBrush" Color="Blue"/>
  </Window.Resources>
  
  
  <StackPanel>
	<StackPanel.Resources>
		<SolidColorBrush x:Key="MyBrush2" Color="Red"/>
	</StackPanel.Resources>
	
    <Button Content="Button 1"
      Background="{StaticResource MyBrush}"/>
    <Button Content="Button 2"
      Background="{StaticResource MyBrush2}"/>
  </StackPanel>
</Window>

MyBrushはこのWindowノードで定義したリソースで、Windowノードとその子ノード内からアクセスできます。
MyBrush2はStackPanelノードで定義したリソースで、StackPanelノードとその子ノード内からアクセスできます。


外部リソース 編集

リソースのみを記述したXAMLファイルを外部リソースと呼びます。
外部リソースはルートノードにResourceDictionaryノードを使って記述します。

  1. <!-- MyResourceDictionary.xaml -->
  2. <ResourceDictionary
  3. 	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. 	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  5.  
  6. 	<SolidColorBrush x:Key="MyBrush" Color="Blue"/>
  7. </ResourceDictionary>


外部リソースを使用するには、Resourceノードに「ResourceDictionaryノード」を使って読み込みたいリソースファイルのパスを指定します。

  1. <Window x:Class="WpfApplication1.MainWindow"
  2.   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.   Title="MainWindow" Height="100" Width="200">
  5. 	<Window.Resources>
  6. 		<ResourceDictionary Source="MyResourceDictionary.xaml"/>
  7. 	</Window.Resources>
  8.  
  9. 	<StackPanel>
  10. 		<Button Content="Button 1" Background="{StaticResource MyBrush}"/>
  11. 	</StackPanel>
  12. </window>

複数のリソースを定義したり外部リソースファイルを読み込みたい場合は、下記のようにします。

  1. <Window x:Class="WpfApplication1.MainWindow"
  2.   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.   Title="MainWindow" Height="100" Width="200">
  5. 	<Window.Resources>
  6. 		<ResourceDictionary>
  7. 			<ResourceDictionary.MergedDictionaries>
  8. 				<ResourceDictionary Source="MyResourceDictionary.xaml"/>
  9. 				<ResourceDictionary Source="MyResourceDictionary2.xaml"/>
  10. 				<ResourceDictonary>
  11. 					<SolidColorBrush x:Key="LocalResource" Color="Red" />
  12. 				</ResourceDictonary>
  13. 			</ResourceDictionary.MergedDictionaries>
  14. 		</ResourceDictionary>
  15. 	</Window.Resources>
  16.  
  17. 	<StackPanel>
  18. 		<Button Content="Button 1" Background="{StaticResource MyBrush}"/>
  19. 	</StackPanel>
  20. </window>

リソースの動的読み込み(XAML) 編集

XAMLは基本的にコンパイル時にソースコードにビルドされ、リソースとしてパッケージ化することは殆どありません。 しかし、どうしても動的にXAMLを編集するなどしてランタイムビルドを行い、作成されたXAMLからUIを作成したい場合にはリソースを動的に読み込む必要があります。

ここではプロジェクトにリソースディレクトリファイルを作成し、そこにDataTemplateを記述してそれをC#のコードで読み出すサンプルを作成してみます。


  1. <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  2. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  3.     <DataTemplate x:Key="MyDataTemplate">
  4.         <StackPanel Orientation="Vertical">
  5.             <TextBlock Text="きちがい" />
  6.             <TextBlock Text="{Binding FileSize}" />
  7.             <TextBlock Text="{Binding LastModified}" />
  8.         </StackPanel>
  9.     </DataTemplate>
  10. </ResourceDictionary>

リソースディレクトリファイルの名前は「Dictionary1.xaml」とします。このままではこのファイルはリソースとして認識されないため、このファイルのプロパティから「ビルドアクション」を「Resource」に設定します。

次にXAMLファイルを動的に読み込むコードです。

  1. Uri uri = new Uri("Dictionary1.xaml", UriKind.Relative);
  2. StreamResourceInfo info = Application.GetResourceStream(uri);
  3. XamlReader reader = new XamlReader();
  4. var resourceDir = reader.LoadAsync(info.Stream) as ResourceDictionary;
  5.  
  6. //
  7. // Dictionary1.xamlに含まれた名前付きのコントロールを読み込んでみる
  8. var dt =resourceDir["MyDataTemplate"] as DataTemplate;
  9. FileStatsViewTemplate = dt;
  10. return FileStatsViewTemplate;

読み込むリソースファイルの場所を指定するにが、上記のようにローカルパスを明示するか、

  1. private const string uriPath = "pack://application:,,,/Resources/Dictionary1.xaml";

のような、アセンブリ名も含めた完全なURIパス文字列を使用します。

スタイル 編集

HTMLにおけるCSSのようなものです。
WPFでも視覚効果とUIの構造は分離していく構想を持っているため、ボタンに表示する文字のフォントや大きさなどはスタイルという形で構造とは別に定義していくことが可能です。

スタイルの記述 編集

スタイルはリソースなので、Resources内に記述するか外部リソースファイルに記述します。

スタイルはStyleノードを使って記述します。
TargetType属性は指定したコントロールのすべてのインスタンスに対して適応します。
x:Key属性をつけると明示的にその名前を参照しない限り、スタイルは適応されません。

<Style TargetType="Button">
	<Setter Property="Background" Value="DarkSeaGreen" />
</Style>
 
<Style x:Key="MyCustomButton">
	<Setter Property="Background" Value="DarkSeaGreen" />
</Style>

スタイルの適応 編集

<!-- スタイルの自動適用 -->
<Button Content="ボタン1" />
 
<!-- x:Key を指定して明示的にスタイルを適用 -->
<Button Style="{StaticResource MyCustomButton}"
	  Content="ボタン2" />
 
<!-- スタイルを直接記述 -->
<Button Content="ボタン3">
<Button.Style>
  <Style TargetType="Button">
	<Setter Property="Background" Value="Gray" />
  </Style>
</Button.Style>
</Button>

またスタイルは継承されます。
TargetType属性で定義されたスタイルは最上位レベルでスタイルが適応されます。

トリガー 編集

動的に変化する値によって適応するスタイルを変更する仕組みとしてトリガーがあります。

<StackPanel Width="60">
  <StackPanel.Resources>
    <Style TargetType="TextBox">
      <Setter Property="Background" Value="LightGray" />
 
      <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True"> <!-- TextBox.IsMouseOverの値がTrueの時に適応するスタイル -->
          <Setter Property="Background" Value="LightBlue" />
        </Trigger>
        <Trigger Property="IsFocused" Value="True">
          <Setter Property="Background" Value="LightPink" />
        </Trigger>
      </Style.Triggers>
    </Style>
  </StackPanel.Resources>
 
  <TextBox Text="テキスト" />
</StackPanel>

このように定義したTextBoxでは、マウスがTextBoxの上にある場合に背景が「水色」になります。

トリガーの種類
Ttigger 特定のプロパティの値の変化をトリガーとして、Setterを用いてプロパティ値を変更する。
MultiTrigger Triggerを複数条件に対応させたもの。指定したすべての条件が満たされた場合にトリガーがかかる。

複数のTriggerを記述します。

DataTrigger スタイル適用先のUI要素だけでなく、データ・バインディングされたデータを監視する。
MultiDataTrigger DataTriggerを複数条件に対応させたもの。指定したすべての条件が満たされた場合にトリガーがかかる。

複数のDataTriggerを記述します。

EventTrigger プロパティ値の変化ではなく、イベントの発生をトリガーとする。また、Setterではなくストーリーボードを使ったアニメーションによりプロパティ値を変化させる。

テンプレート 編集

コントロールテンプレート 編集

スタイルはコントロールで用意されているプロパティの値を再設定し、視覚効果をカスタマイズするものでしたが、コントロールテンプレートはコントロールの構造そのものを再定義します。

コントロールテンプレートを使うとButtonコントロールの形状を変更することができます。(不完全)

<Button>
  <Button.Template>
    <ControlTemplate TargetType="Button">
      <Ellipse Fill="LightBlue" Width="80" Height="30"/>
    </ControlTemplate>
  </Button.Template>
</Button>

スタイルと同じように、コントロールテンプレートの適応にも自動適応があります。

<StackPanel>
  <StackPanel.Resources>
    <ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
      <Ellipse Fill="LightBlue" Width="80" Height="30"/>
    </ControlTemplate>
  </StackPanel.Resources>
 
  <Button Template="{StaticResource MyButtonTemplate}" />
 
</StackPanel>

コントロールテンプレートも外部リソースファイルに記述することができます。

ContentPresenterとTemplateBining 編集

先ほどのボタンのコントロールテンプレートは、元のButtonのレイアウトを上書きするものでした。
そのため、通常ならばButtonの表面に表示されるはずのテキストなどを表示していた元のレイアウトが上書きされ、何も表示されなかったのです。

そこで、もともとのButtonコントロールがもつレイアウトを使いつつ、レイアウトをカスタマイズする方法としてContentPresenterを使用します。
Buttonクラスは、ボタンの表面に表示する文字をContentプロパティで設定しています。
Contentプロパティはその内容を出力する際にコントロールテンプレートを使って表示する機能を持っています。

<Button>
  <Button.Template>
    <ControlTemplate TargetType="Button">
	  <Grid>
		<Ellipse Fill="{TemplateBining Background}" Width="80" Height="30"/>
		<ContentPresenter
                HorizontalAlignment="Center"
                VerticalAlignment="Center
	  </Grid>
    </ControlTemplate>
  </Button.Template>
</Button>

ButtonクラスはContentプロパティに設定されたものをそのままstring型としてContentPresenterを作成します。
ContentPresenterは、string型は与えられた場合、その文字列をTextBlockを使って描画します。

TemplateBiningはコントロール内で使用するバインディングのマークアップ文字です。
テンプレートを設定したコントロール(この場合、Buttonクラス)をターゲットとし、ターゲットのプロパティとバインディングを構築します。 上記の場合、Button.Backgroundプロパティとのバインディングとなります。

データテンプレート 編集

http://msdn.microsoft.com/ja-jp/library/ms742521%28v=vs.80%29.aspx

参照 編集

広告ブロッカーが検出されました。


広告収入で運営されている無料サイトWikiaでは、このたび広告ブロッカーをご利用の方向けの変更が加わりました。

広告ブロッカーが改変されている場合、Wikiaにアクセスしていただくことができなくなっています。カスタム広告ブロッカーを解除してご利用ください。

FANDOMでも見てみる

おまかせWiki