次の方法で共有


XAML の概要

この記事では、XAML 言語の機能について説明し、XAML を使用して Windows Presentation Foundation (WPF) アプリを記述する方法について説明します。 この記事では、WPF によって実装される XAML について具体的に説明します。 XAML 自体は、WPF よりも大きな言語概念です。

XAML とは

XAML は宣言型マークアップ言語です。 .NET プログラミング モデルに適用される XAML は、.NET アプリの UI の作成を簡略化します。 宣言型 XAML マークアップで表示される UI 要素を作成し、部分クラス定義を介してマークアップに結合された分離コード ファイルを使用して、UI 定義をランタイム ロジックから分離できます。 XAML は、アセンブリで定義されているバッキング型の特定のセット内のオブジェクトのインスタンス化を直接表します。 これは、他のほとんどのマークアップ言語とは異なり、通常はバッキング型システムに直接結びつかずに解釈される言語です。 XAML を使用すると、異なる可能性のあるツールを使用して、別の関係者がアプリの UI とロジックで作業できるワークフローが可能になります。

テキストとして表される XAML ファイルは、通常、 .xaml 拡張子を持つ XML ファイルです。 ファイルは任意の XML エンコードでエンコードできますが、UTF-8 としてのエンコードが一般的です。

次の例は、UI の一部としてボタンを作成する方法を示しています。 この例は、XAML が一般的な UI プログラミングのメタファーを表す方法を示すことを目的としています (完全なサンプルではありません)。

<StackPanel>
    <Button Content="Click Me"/>
</StackPanel>

XAML 構文の簡単な説明

次のセクションでは、XAML 構文の基本的な形式について説明し、簡単なマークアップの例を示します。 これらのセクションは、バッキング型システムでの表現方法など、各構文形式に関する完全な情報を提供することを意図していません。 XAML 構文の詳細については、「XAML 構文の詳細」を 参照してください

XML 言語に関する以前の知識がある場合は、次のいくつかのセクションの資料の多くが基本になります。 これは、XAML の基本的な設計原則の 1 つの結果です。 XAML 言語は独自の概念を定義しますが、これらの概念は XML 言語とマークアップ形式で機能します。

XAML オブジェクト要素

オブジェクト要素は、通常、型のインスタンスを宣言します。 この型は、XAML を言語として使用するテクノロジによって参照されるアセンブリで定義されます。

オブジェクト要素の構文は、必ず開始の角かっこ (<) で始まります。 その後に、インスタンスを作成する型の名前が続きます。 (名前にはプレフィックス (後で説明する概念) を含めることができます)。その後、必要に応じてオブジェクト要素の属性を宣言できます。 オブジェクト要素タグを完成するには、閉じの角括弧 (>) で終えます。 代わりに、コンテンツのない自己完結形を使用するには、スラッシュと右角かっこ (/>) を使ってタグを完成させます。 たとえば、前に示したマークアップ スニペットをもう一度見てみましょう。

<StackPanel>
    <Button Content="Click Me"/>
</StackPanel>

これは、2 つのオブジェクト要素を指定します: <StackPanel> (コンテンツあり、後で終了タグを使用)、 <Button .../> (複数の属性を持つ自己終了フォーム)。 各オブジェクト要素 StackPanel および Button は、WPF によって定義され、WPF アセンブリの一部であるクラスの名前にマップされます。 オブジェクト要素タグを指定する場合は、基になる型の新しいインスタンスを作成する XAML 処理の命令を作成します。 各インスタンスは、XAML を解析して読み込むときに、基になる型のパラメーターなしのコンストラクターを呼び出すことによって作成されます。

属性構文 (プロパティ)

オブジェクトのプロパティは、多くの場合、オブジェクト要素の属性として表すことができます。 属性構文では、設定するオブジェクト プロパティの名前を指定し、その後に代入演算子 (=) を付けます。 属性の値は、常に引用符内に含まれる文字列として指定されます。

属性構文は、最も合理化されたプロパティ設定構文であり、過去にマークアップ言語を使用した開発者にとって最も直感的な構文です。 たとえば、次のマークアップでは、 Contentの表示テキストを含む赤いテキストと青い背景を持つボタンが作成されます。

<Button Background="Blue" Foreground="Red" Content="This is a button"/>

プロパティ要素の構文

オブジェクト要素の一部のプロパティでは、プロパティ値を指定するために必要なオブジェクトまたは情報を属性構文の引用符と文字列の制限内で適切に表現できないため、属性構文を使用できません。 このような場合は、プロパティ要素構文と呼ばれる別の構文を使用できます。

プロパティ要素の開始タグの構文は <TypeName.PropertyName>。 一般に、そのタグの内容は、プロパティがその値として受け取る型のオブジェクト要素です。 コンテンツを指定した後、終了タグを使用してプロパティ要素を閉じる必要があります。 終了タグの構文は </TypeName.PropertyName>

属性構文が可能な場合は、通常、属性構文を使用する方が便利で、よりコンパクトなマークアップが可能になりますが、多くの場合、技術的な制限ではなく、スタイルの問題です。 次の例では、前の属性構文の例と同じプロパティを設定していますが、今回は Buttonのすべてのプロパティに対してプロパティ要素構文を使用します。

<Button>
    <Button.Background>
        <SolidColorBrush Color="Blue"/>
    </Button.Background>
    <Button.Foreground>
        <SolidColorBrush Color="Red"/>
    </Button.Foreground>
    <Button.Content>
        This is a button
    </Button.Content>
</Button>

コレクション構文

XAML 言語には、人間が判読できるマークアップを生成するいくつかの最適化が含まれています。 このような最適化の 1 つは、特定のプロパティがコレクション型を受け取る場合、マークアップで宣言した項目がそのプロパティの値内の子要素としてコレクションの一部になることです。 この場合、子オブジェクト要素のコレクションは、コレクション プロパティに設定されている値です。

次の例は、 GradientStops プロパティの値を設定するためのコレクション構文を示しています。

<LinearGradientBrush>
    <LinearGradientBrush.GradientStops>
        <!-- no explicit new GradientStopCollection, parser knows how to find or create -->
        <GradientStop Offset="0.0" Color="Red" />
        <GradientStop Offset="1.0" Color="Blue" />
    </LinearGradientBrush.GradientStops>
</LinearGradientBrush>

XAML コンテンツのプロパティ

XAML は言語機能を指定します。クラスは、そのプロパティの 1 つを XAML コンテンツ プロパティとして正確に指定できます。 そのオブジェクト要素の子要素は、そのコンテンツ プロパティの値を設定するために使用されます。 言い換えると、コンテンツ プロパティの場合は、XAML マークアップでそのプロパティを設定するときにプロパティ要素を省略し、マークアップでより目に見える親子メタファーを生成できます。

たとえば、BorderChild プロパティを指定します。 次の 2 つの Border 要素は同じように扱われます。 1 つ目はコンテンツ プロパティ構文を利用し、 Border.Child プロパティ要素を省略します。 2 つ目は、 Border.Child を明示的に示しています。

<Border>
    <TextBox Width="300"/>
</Border>
<!--explicit equivalent-->
<Border>
    <Border.Child>
        <TextBox Width="300"/>
    </Border.Child>
</Border>

XAML 言語のルールとして、XAML コンテンツ プロパティの値は、そのオブジェクト要素の他のプロパティ要素の完全な前または後に指定する必要があります。 たとえば、次のマークアップはコンパイルされません。

<Button>I am a
  <Button.Background>Blue</Button.Background>
  blue button</Button>

XAML 構文の詳細については、「XAML 構文の詳細」を 参照してください

テキスト コンテンツ

少数の XAML 要素は、テキストをコンテンツとして直接処理できます。 これを有効にするには、次のいずれかのケースが true である必要があります。

  • クラスはコンテンツ プロパティを宣言する必要があり、そのコンテンツ プロパティは文字列に割り当て可能な型である必要があります (型は Object可能性があります)。 たとえば、ContentControlはコンテンツ プロパティとしてContentを使用し、種類は Object であり、ContentControl: Buttonなどの<Button>Hello</Button>での次の使用方法をサポートします。

  • 型コンバーターを宣言する必要があります。この場合、テキスト コンテンツはその型コンバーターの初期化テキストとして使用されます。 たとえば、<Brush>Blue</Brush>Blueのコンテンツ値をブラシに変換します。 このケースは、実際にはあまり一般的ではありません。

  • 型は、既知の XAML 言語プリミティブである必要があります。

コンテンツプロパティとコレクション構文の組み合わせ

この例を考えてみましょう。

<StackPanel>
    <Button>First Button</Button>
    <Button>Second Button</Button>
</StackPanel>

ここで、各 ButtonStackPanelの子要素です。 これは、2 つの異なる理由で 2 つのタグを省略する、合理化された直感的なマークアップです。

  • 省略された StackPanel.Children プロパティ要素:StackPanelPanelから派生します。 Panel は、 Panel.Children を XAML コンテンツ プロパティとして定義します。

  • 省略された UIElementCollection オブジェクト要素:Panel.Children プロパティは、UIElementCollectionを実装する型IListを受け取ります。 コレクションの要素タグは、 IListなどのコレクションを処理するための XAML 規則に基づいて省略できます。 (この場合、 UIElementCollection はパラメーターなしのコンストラクターを公開しないため、実際にはインスタンス化できません。そのため、 UIElementCollection オブジェクト要素がコメント アウトされて表示されます)。

<StackPanel>
    <StackPanel.Children>
        <!--<UIElementCollection>-->
        <Button>First Button</Button>
        <Button>Second Button</Button>
        <!--</UIElementCollection>-->
    </StackPanel.Children>
</StackPanel>

属性構文 (イベント)

属性構文は、プロパティではなくイベントであるメンバーにも使用できます。 この場合、属性の名前はイベントの名前です。 XAML のイベントの WPF 実装では、属性の値は、そのイベントのデリゲートを実装するハンドラーの名前です。 たとえば、次のマークアップは、マークアップで作成されたClickButton イベントのハンドラーを割り当てます。

<Button Click="Button_Click" >Click Me!</Button>

WPF のイベントと XAML には、属性構文のこの例以外にも多くのものがあります。 たとえば、ここで参照されている ClickHandler が何を表し、どのように定義されているか疑問に思うかもしれません。 これについては、この記事の今後の イベントと XAML 分離コード のセクションで説明します。

XAML の大文字と小文字と空白

一般に、XAML では大文字と小文字が区別されます。 バッキング型を解決するために、WPF XAML は CLR で大文字と小文字が区別されるのと同じ規則によって大文字と小文字が区別されます。 オブジェクト要素、プロパティ要素、属性名はすべて、名前で比較する際に、アセンブリ内の基になる型または型のメンバーと大小文字の区別を考慮して指定する必要があります。 XAML 言語のキーワードとプリミティブでも大文字と小文字が区別されます。 値は常に大文字と小文字が区別されるわけではありません。 値のケース・センシティビティは、値を受け取るプロパティに関連付けられた型コンバーターの動作やプロパティ値タイプによって異なります。 たとえば、 Boolean 型を受け取るプロパティは、 true または True を同等の値として受け取ることができますが、文字列から Boolean へのネイティブ WPF XAML パーサー型変換で既に同等の値として許可されているためです。

WPF XAML プロセッサとシリアライザーは、重要でないすべての空白を無視または削除し、重要な空白を正規化します。 これは、XAML 仕様の既定の空白動作の推奨事項と一致します。 この動作は、XAML コンテンツ プロパティ内で文字列を指定した場合にのみ発生します。 最も簡単に言うと、XAML はスペース、改行、タブ文字をスペースに変換し、連続する文字列のいずれかの末尾に見つかった場合は 1 つのスペースを保持します。 XAML の空白処理の詳細については、この記事では説明しません。 詳細については、「 XAML での空白処理」を参照してください。

マークアップ拡張機能

マークアップ拡張は XAML 言語の概念です。 属性構文の値を指定するために使用する場合、中かっこ ({}) はマークアップ拡張の使用法を示します。 この使用法により、XAML 処理は、属性値の一般的な処理からリテラル文字列または文字列変換可能な値としてエスケープするように指示されます。

WPF アプリプログラミングで使用される最も一般的なマークアップ拡張機能は、 Binding、データ バインディング式に使用され、リソース参照 StaticResourceDynamicResourceです。 マークアップ拡張を使用すると、属性構文を使用して、そのプロパティが一般的に属性構文をサポートしていない場合でも、プロパティの値を指定できます。 マークアップ拡張では、多くの場合、中間式の型を使用して、値の遅延や実行時にのみ存在する他のオブジェクトの参照などの機能を有効にします。

たとえば、次のマークアップは、属性構文を使用して Style プロパティの値を設定します。 Style プロパティは、Style クラスのインスタンスを受け取ります。既定では、属性構文文字列ではインスタンス化できませんでした。 ただし、この場合、属性は特定のマークアップ拡張機能 ( StaticResource) を参照します。 そのマークアップ拡張機能が処理されると、リソース ディクショナリでキー付きリソースとして以前にインスタンス化されたスタイルへの参照が返されます。

<Window x:Class="index.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="100" Width="300">
    <Window.Resources>
        <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
        <Style TargetType="Border" x:Key="PageBackground">
            <Setter Property="BorderBrush" Value="Blue"/>
            <Setter Property="BorderThickness" Value="5" />
        </Style>
    </Window.Resources>
    <Border Style="{StaticResource PageBackground}">
        <StackPanel>
            <TextBlock Text="Hello" />
        </StackPanel>
    </Border>
</Window>

WPF で特に実装されている XAML のすべてのマークアップ拡張機能のリファレンス リストについては、「 WPF XAML 拡張機能」を参照してください。 System.Xaml で定義され、.NET XAML 実装でより広く使用できるマークアップ拡張機能のリファレンス リストについては、「 XAML 名前空間 (x:) 言語機能」を参照してください。 マークアップ拡張機能の概念の詳細については、「 マークアップ拡張機能と WPF XAML」を参照してください。

型変換器

簡単な XAML 構文 」セクションでは、属性値を文字列で設定できる必要があることを示しました。 文字列を他のオブジェクト型またはプリミティブ値に変換する方法の基本的なネイティブ処理は、StringDateTimeなどの特定の型のネイティブ処理と共に、Uri型自体に基づいています。 ただし、これらの型の多くの WPF 型またはメンバーは、より複雑なオブジェクト型のインスタンスを文字列および属性として指定できるように、基本的な文字列属性処理動作を拡張します。

Thickness構造体は、XAML の使用に対して型変換が有効になっている型の例です。 Thickness は、入れ子になった四角形内の測定値を示し、 Marginなどのプロパティの値として使用されます。 Thicknessに型コンバーターを配置することで、Thicknessを使用するすべてのプロパティは、属性として指定できるため、XAML で指定する方が簡単です。 次の例では、型変換と属性構文を使用して、 Marginの値を指定します。

<Button Margin="10,20,10,30" Content="Click me"/>

前の属性構文の例は、次のより詳細な構文の例と同じです。ここで、 Margin は、 Thickness オブジェクト要素を含むプロパティ要素構文を使用して設定されます。 Thicknessの 4 つの主要なプロパティは、新しいインスタンスの属性として設定されます。

<Button Content="Click me">
    <Button.Margin>
        <Thickness Left="10" Top="20" Right="10" Bottom="30"/>
    </Button.Margin>
</Button>

また、型自体にパラメーターなしのコンストラクターがないため、サブクラスを使用せずにプロパティをその型に設定する唯一のパブリックな方法は、型変換が唯一のパブリックな方法であるオブジェクトの数も限られています。 たとえば Cursor です。

型変換の詳細については、「 TypeConverters と XAML」を参照してください。

ルート要素と名前空間

適切な形式の XML ファイルと有効な XAML ファイルの両方にするには、XAML ファイルにルート要素が 1 つだけ必要です。 一般的な WPF シナリオでは、WPF アプリ モデルで顕著な意味を持つルート要素 (ページの WindowPage 、外部ディクショナリの ResourceDictionary 、アプリ定義の Application など) を使用します。 次の例は、WPF ページの一般的な XAML ファイルのルート要素と、 Pageのルート要素を示しています。

<Page x:Class="index.Page1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Page1">

</Page>

ルート要素には、 xmlns 属性と xmlns:x属性も含まれます。 これらの属性は、マークアップが要素として参照するバックエンドの型の型定義が含まれる XAML 名前空間を XAML プロセッサで特定します。 xmlns属性は、既定の XAML 名前空間を具体的に示します。 既定の XAML 名前空間内では、マークアップ内のオブジェクト要素をプレフィックスなしで指定できます。 ほとんどの WPF アプリ シナリオと、SDK の WPF セクションで提供されるほぼすべての例では、既定の XAML 名前空間が WPF 名前空間 http://schemas.microsoft.com/winfx/2006/xaml/presentationにマップされます。 xmlns:x属性は、XAML 言語名前空間をhttp://schemas.microsoft.com/winfx/2006/xamlマップする追加の XAML 名前空間を示します。

名前スコープの使用とマッピングのスコープを定義するための xmlns の使用は、XML 1.0 仕様と一致します。 XAML 名前スコープは、XAML 名前スコープが型解決と XAML の解析に関して、名前スコープの要素が型によってどのようにサポートされるかを意味するという点でのみ、XML 名前スコープとは異なります。

xmlns属性は、各 XAML ファイルのルート要素でのみ必要です。 xmlns 定義はルート要素のすべての子孫要素に適用されます (この動作は、 xmlnsの XML 1.0 仕様と再び一致します)。 xmlns 属性はルートの下の他の要素でも許可され、定義要素の子孫要素にも適用されます。 ただし、XAML 名前空間の定義や再定義が頻繁に行われると、XAML マークアップ スタイルが読みにくい場合があります。

XAML プロセッサの WPF 実装には、WPF コア アセンブリを認識するインフラストラクチャが含まれています。 WPF コア アセンブリには、既定の XAML 名前空間への WPF マッピングをサポートする型が含まれていることがわかっています。 これは、プロジェクト ビルド ファイルと WPF ビルドおよびプロジェクト システムの一部である構成によって有効になります。 そのため、既定の XAML 名前空間を既定の xmlns として宣言することは、WPF アセンブリから取得された XAML 要素を参照するために必要なすべてです。

x: プレフィックス

前のルート要素の例では、プレフィックス x: を使用して XAML 名前空間 http://schemas.microsoft.com/winfx/2006/xamlをマップしました。これは、XAML 言語コンストラクトをサポートする専用の XAML 名前空間です。 この x: プレフィックスは、プロジェクトのテンプレート、例、およびこの SDK 全体のドキュメントで、この XAML 名前空間をマッピングするために使用されます。 XAML 言語の XAML 名前空間には、XAML で頻繁に使用するいくつかのプログラミングコンストラクトが含まれています。 使用する最も一般的な x: プレフィックス プログラミングコンストラクトの一覧を次に示します。

  • x:Key: ResourceDictionary 内のリソースごとに一意のキーを設定します (または、他のフレームワークでは同様のディクショナリの概念)。 x:Key は、一般的な WPF アプリのマークアップで表示される x: の使用量の 90% を占める可能性があります。

  • x:Class: XAML ページの分離コードを提供するクラスの CLR 名前空間とクラス名を指定します。 WPF プログラミング モデルごとに分離コードをサポートするには、このようなクラスが必要です。そのため、リソースがない場合でも、ほとんどの場合、 x: がマップされます。

  • x:Name: オブジェクト要素の処理後に実行時コードに存在するインスタンスのランタイム オブジェクト名を指定します。 一般に、 x:Name には WPF で定義された同等のプロパティを頻繁に使用します。 このようなプロパティは、特に CLR バッキング プロパティにマップされるため、ランタイム コードを使用して初期化された XAML から名前付き要素を検索する場合に、アプリ プログラミングに便利です。 このような最も一般的なプロパティは FrameworkElement.Nameです。 特定の型で同等の WPF フレームワーク レベルの プロパティがサポートされていない場合でも、Name を使用できます。 これは、特定のアニメーション シナリオで発生します。

  • x:Static: XAML と互換性のあるプロパティではない静的な値を返す参照を有効にします。

  • x:Type: 型名に基づいて Type 参照を構築します。 これは、Typeなど、Style.TargetTypeを受け取る属性を指定するために使用されますが、多くの場合、プロパティにはネイティブの文字列からTypeへの変換があり、x:Type マークアップ拡張の使用は省略可能です。

x: プレフィックス/XAML 名前空間には追加のプログラミングコンストラクトがありますが、これはあまり一般的ではありません。 詳細については、「 XAML 名前空間 (x:) 言語機能」を参照してください。

カスタムプレフィックスとカスタム型

独自のカスタム アセンブリ、または PresentationCorePresentationFrameworkWindowsBase の WPF コア外のアセンブリの場合は、カスタム xmlns マッピングの一部としてアセンブリを指定できます。 その後、試みている XAML 使用法をサポートするためにその型が正しく実装されている限り、XAML でそのアセンブリから型を参照できます。

XAML マークアップでのカスタム プレフィックスの動作の基本的な例を次に示します。 プレフィックス custom はルート要素タグで定義され、パッケージ化され、アプリで使用できる特定のアセンブリにマップされます。 このアセンブリには、一般的な XAML の使用をサポートするために実装される NumericUpDown型と、WPF XAML コンテンツ モデルのこの特定のポイントでの挿入を許可するクラス継承の使用が含まれています。 この NumericUpDown コントロールのインスタンスは、プレフィックスを使用してオブジェクト要素として宣言されます。これにより、XAML パーサーは、どの XAML 名前空間に型が含まれているか、したがって、型定義を含むバッキング アセンブリが認識されます。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:custom="clr-namespace:NumericUpDownCustomControl;assembly=CustomLibrary"
    >
  <StackPanel Name="LayoutRoot">
    <custom:NumericUpDown Name="numericCtrl1" Width="100" Height="60"/>
...
  </StackPanel>
</Page>

XAML のカスタム型の詳細については、「 XAML と WPF のカスタム クラス」を参照してください。

アセンブリ内の XML 名前空間とコード名前空間の関連の詳細については、「 WPF XAML の XAML 名前空間と名前空間マッピング」を参照してください。

イベントと XAML コードビハインド

ほとんどの WPF アプリは、XAML マークアップと分離コードの両方で構成されています。 プロジェクト内では、XAML は .xaml ファイルとして書き込まれ、分離コード ファイルの記述には Microsoft Visual Basic や C# などの CLR 言語が使用されます。 XAML ファイルが WPF プログラミング モデルおよびアプリケーション モデルの一部としてマークアップ コンパイルされている場合、XAML ファイルの XAML 分離コード ファイルの場所は、XAML のルート要素の x:Class 属性として名前空間とクラスを指定することによって識別されます。

これまでの例では、いくつかのボタンを見てきましたが、これらのボタンの中には、まだ論理的な動作が関連付けされていませんでした。 オブジェクト要素の動作を追加するための主なアプリケーション レベルのメカニズムは、要素クラスの既存のイベントを使用し、実行時にそのイベントが発生したときに呼び出されるそのイベントの特定のハンドラーを記述することです。 使用するハンドラーのイベント名と名前はマークアップで指定されますが、ハンドラーを実装するコードは分離コードで定義されます。

<Page x:Class="ExampleNamespace.ExamplePage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <Button Click="Button_Click">Click me</Button>
    </StackPanel>
</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace ExampleNamespace;

public partial class ExamplePage : Page
{
    public ExamplePage() =>
        InitializeComponent();

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var buttonControl = (Button)e.Source;
        buttonControl.Foreground = Brushes.Red;
    }
}
Class ExamplePage
    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        Dim buttonControl = DirectCast(e.Source, Button)
        buttonControl.Foreground = Brushes.Red
    End Sub
End Class

分離コード ファイルは CLR 名前空間 ExampleNamespace を使用し (名前空間は Visual Basic では表示されません)、 ExamplePage をその名前空間内の部分クラスとして宣言していることに注意してください。 これにより、x:ClassExampleNamespace属性値が並列化されます。 ExamplePage マークアップ ルートで提供された WPF マークアップ コンパイラは、ルート要素型からクラスを派生させることで、コンパイル済み XAML ファイルの部分クラスを作成します。 同じ部分クラスも定義する分離コードを提供すると、結果のコードはコンパイル済みアプリの同じ名前空間とクラス内で結合されます。

重要

Visual Basic では、ルート名前空間は XAML と分離コードの両方に暗黙的に適用されます。 入れ子になった名前空間のみが表示されます。 この記事では、C# プロジェクトの XAML について説明します。

WPF での分離コード プログラミングの要件の詳細については、「WPF の 分離コード、イベント ハンドラー、部分クラスの要件」を参照してください。

別の分離コード ファイルを作成しない場合は、XAML ファイルにコードをインライン化することもできます。 ただし、インライン コードは汎用性の低い手法であり、大きな制限があります。 詳細については、「 WPF のCode-Behind と XAML」を参照してください。

ルーティングイベント

WPF の基礎となる特定のイベント機能は、ルーティング イベントです。 ルーティング イベントを使用すると、要素がツリーリレーションシップを介して接続されている限り、別の要素によって発生したイベントを処理できます。 XAML 属性を使用してイベント処理を指定する場合、ルーティング イベントは、クラス メンバー テーブル内の特定のイベントを一覧表示しない要素を含め、任意の要素でリッスンして処理できます。 これを行うには、所有するクラス名でイベント名属性を修飾します。 たとえば、実行中のStackPanelStackPanel / 例の親Buttonは、子要素のボタンClickイベントに対してハンドラーを登録する際に、ハンドラー名を属性値としてButton.Clickオブジェクト要素にStackPanel属性を指定することができます。 詳細については、「 ルーティング イベントの概要」を参照してください。

名前付き要素

既定では、XAML オブジェクト要素を処理してオブジェクト グラフに作成されるオブジェクト インスタンスには、一意の識別子またはオブジェクト参照がありません。 これに対し、コードでコンストラクターを呼び出す場合は、ほとんどの場合、コンストラクターの結果を使用して変数を構築されたインスタンスに設定し、後でコードでインスタンスを参照できるようにします。 マークアップ定義を使用して作成されたオブジェクトへの標準化されたアクセスを提供するために、XAML は x:Name 属性を定義します。 x:Name属性の値は、任意のオブジェクト要素に設定できます。 分離コードでは、選択した識別子は、構築されたインスタンスを参照するインスタンス変数と同じです。 すべての点で、名前付き要素はオブジェクト インスタンス (そのインスタンスを参照する名前) であるかのように機能し、分離コードは名前付き要素を参照してアプリ内での実行時の相互作用を処理できます。 インスタンスと変数の間のこの接続は、WPF XAML マークアップ コンパイラによって実現されます。具体的には、この記事では詳しく説明しない InitializeComponent などの機能とパターンが含まれます。

WPF フレームワーク レベルの XAML 要素は、 Name プロパティを継承します。これは、XAML で定義された x:Name 属性と同等です。 他の特定のクラスでは、 x:Nameのプロパティ レベルの同等のクラスも提供されます。これは通常、 Name プロパティとしても定義されます。 一般に、選択した要素/型のメンバー テーブルに Name プロパティが見つからない場合は、代わりに x:Name を使用します。 x:Name値は、特定のサブシステムまたは FindName などのユーティリティ メソッドによって実行時に使用できる XAML 要素に識別子を提供します。

次の例では、Name要素にStackPanelを設定します。 次に、そのButton内のStackPanelのハンドラーは、StackPanelによって設定されたインスタンス参照buttonContainerを介してNameを参照します。

<StackPanel Name="buttonContainer">
    <Button Click="RemoveThis_Click">Click to remove this button</Button>
</StackPanel>
private void RemoveThis_Click(object sender, RoutedEventArgs e)
{
    var element = (FrameworkElement)e.Source;
    
    if (buttonContainer.Children.Contains(element))
        buttonContainer.Children.Remove(element);
}
Private Sub RemoveThis_Click(sender As Object, e As RoutedEventArgs)
    Dim element = DirectCast(e.Source, FrameworkElement)

    If buttonContainer.Children.Contains(element) Then
        buttonContainer.Children.Remove(element)
    End If
End Sub

変数と同様に、インスタンスの XAML 名はスコープの概念によって制御されるため、予測可能な特定のスコープ内で名前を一意に適用できます。 ページを定義するプライマリ マークアップは、1 つの一意の XAML 名前スコープを表し、XAML 名前スコープの境界がそのページのルート要素です。 ただし、他のマークアップ ソースは、スタイル内のスタイルやテンプレートなど、実行時にページと対話できます。このようなマークアップ ソースには、ページの XAML 名前スコープに必ずしも接続しない独自の XAML 名前スコープが用意されていることがよくあります。 x:Nameと XAML 名前スコープの詳細については、「Namex:Name ディレクティブ、または WPF XAML 名前スコープ」を参照してください。

添付プロパティと添付イベント

XAML では、設定されている要素の型の定義にプロパティまたはイベントが存在しない場合でも、特定のプロパティまたはイベントを任意の要素で指定できるようにする言語機能を指定します。 この機能のプロパティ バージョンは添付プロパティと呼ばれ、イベントのバージョンは添付イベントと呼ばれます。 概念的には、添付プロパティと添付イベントは、任意の XAML 要素/オブジェクト インスタンスに設定できるグローバル メンバーと考えることができます。 ただし、その要素/クラスまたはより大きなインフラストラクチャでは、添付値のバッキング プロパティ ストアをサポートする必要があります。

XAML の添付プロパティは、通常、属性構文を使用して使用されます。 属性構文では、フォーム ownerType.propertyNameで添付プロパティを指定します。

表面的には、これはプロパティ要素の使用法に似ていますが、この場合、指定する ownerType は、添付プロパティが設定されているオブジェクト要素とは常に異なる型になります。 ownerType は、XAML プロセッサが添付プロパティ値を取得または設定するために必要なアクセサー メソッドを提供する型です。

添付プロパティの最も一般的なシナリオは、子要素がプロパティ値を親要素に報告できるようにすることです。

次の例は、 DockPanel.Dock 添付プロパティを示しています。 DockPanel クラスは、DockPanel.Dockのアクセサーを定義し、添付プロパティを所有します。 DockPanel クラスには、その子要素を反復処理し、各要素でDockPanel.Dockの設定値を具体的にチェックするロジックも含まれています。 値が見つかった場合、その値は、レイアウト中に子要素を配置するために使用されます。 DockPanel.Dock添付プロパティとこの配置機能の使用は、実際には、DockPanel クラスの動機付けシナリオです。

<DockPanel>
    <Button DockPanel.Dock="Left" Width="100" Height="20">I am on the left</Button>
    <Button DockPanel.Dock="Right" Width="100" Height="20">I am on the right</Button>
</DockPanel>

WPF では、ほとんどの添付プロパティまたはすべての添付プロパティも依存関係プロパティとして実装されます。 詳細については、「 添付プロパティの概要」を参照してください。

添付イベントでは、同様の ownerType.eventName 形式の属性構文が使用されます。 アタッチされていないイベントと同様に、XAML の添付イベントの属性値は、要素でイベントが処理されるときに呼び出されるハンドラー メソッドの名前を指定します。 WPF XAML での添付イベントの使用はあまり一般的ではありません。 詳細については、「 添付イベントの概要」を参照してください。

基本型

基になる WPF XAML とその XAML 名前空間は、XAML の CLR オブジェクトとマークアップ要素に対応する型のコレクションです。 ただし、すべてのクラスを要素にマップできるわけではありません。 などの抽象クラスと、特定の非抽象基底クラスは、CLR オブジェクト モデルの継承に使用されます。 抽象クラスを含む基底クラスは、XAML 開発にとって依然として重要です。具体的な XAML 要素はそれぞれ、その階層内の一部の基底クラスからメンバーを継承するためです。 多くの場合、これらのメンバーには、要素の属性として設定できるプロパティや、処理できるイベントが含まれます。 FrameworkElement は、WPF フレームワーク レベルの WPF の具象基本 UI クラスです。 UI を設計するときは、さまざまな図形、パネル、デコレーター、またはコントロール クラスを使用します。これらはすべて FrameworkElementから派生します。 関連する基底クラス FrameworkContentElementでは、 FrameworkElementの API を意図的にミラーリングする API を使用して、フロー レイアウト プレゼンテーションに適したドキュメント指向の要素をサポートします。 要素レベルの属性と CLR オブジェクト モデルの組み合わせにより、特定の XAML 要素とその基になる型に関係なく、ほとんどの具体的な XAML 要素で設定できる一連の共通プロパティが提供されます。

安全

XAML は、オブジェクトのインスタンス化と実行を直接表すマークアップ言語です。 そのため、XAML で作成された要素は、アプリ コードと同じシステム リソース (ネットワーク アクセス、ファイル システム IO など) と対話できます。 XAML には、ホスティング アプリと同じシステム リソースへのアクセス権もあります。

WPF のコード アクセス セキュリティ (CAS)

.NET Framework とは異なり、WPF for .NET は CAS をサポートしていません。 詳細については、「 コード アクセス セキュリティの相違点」を参照してください。

コードから XAML を読み込む

XAML を使用してすべての UI を定義できますが、XAML で UI の一部のみを定義することも適切な場合があります。 この機能は、次の用途に使用できます。

  • 部分カスタマイズを有効にします。
  • UI 情報のローカル ストレージ。
  • ビジネス オブジェクトをモデル化します。

これらのシナリオの鍵となるのは、 XamlReader クラスとその Load メソッドです。 入力は XAML ファイルであり、出力は、そのマークアップから作成されたオブジェクトのすべての実行時ツリーを表すオブジェクトです。 その後、アプリに既に存在する別のオブジェクトのプロパティとしてオブジェクトを挿入できます。 プロパティがコンテンツ モデルにあり、新しいコンテンツがアプリに追加されたことを実行エンジンに通知する表示機能がある限り、XAML で動的に読み込むことで、実行中のアプリのコンテンツを簡単に変更できます。

こちらも参照ください