次の方法で共有


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

XAML フレームワークでコントロール テンプレートを作成することで、コントロールのビジュアル構造と視覚的な動作をカスタマイズできます。 コントロールには、 背景前景FontFamily などの多くのプロパティがあり、コントロールの外観のさまざまな側面を指定するように設定できます。 ただし、これらのプロパティを設定することで行うことができる変更は制限されます。 ControlTemplate クラスを使用してテンプレートを作成することで、追加のカスタマイズを指定できます。 ここでは、CheckBox コントロールの外観をカスタマイズする ControlTemplate を作成する方法について説明します。

重要な API: ControlTemplate クラスControl.Template プロパティ

カスタム コントロール テンプレートの例

既定では、 CheckBox コントロールは、その内容 (文字列または CheckBox の横にあるオブジェクト) を選択ボックスの右側に配置し、チェック マークは、ユーザーが CheckBox を選択したことを示します。 これらの特性は、 CheckBox の視覚的な構造と視覚的な動作を表します。

、およびの状態に表示される既定の Unchecked を使用した Indeterminate を次に示します。

既定のチェック ボックス テンプレート

これらの特性を変更するには、CheckBoxControlTemplate を作成します。 たとえば、チェック ボックスの内容を選択ボックスの下に表示し、 X を使用してユーザーがチェック ボックスを選択したことを示す場合です。 これらの特性は、CheckBoxControlTemplate で指定します。

コントロールでカスタム テンプレートを使用するには、 ControlTemplate をコントロールの Template プロパティに割り当てます。 次に、CheckBox を示します。この CheckBox は、ControlTemplate を使用するもので、CheckBoxTemplate1と呼ばれます。 次のセクションでは、 ControlTemplate の拡張アプリケーション マークアップ言語 (XAML) を示します。

<CheckBox Content="CheckBox" Template="{StaticResource CheckBoxTemplate1}" IsThreeState="True" Margin="20"/>

テンプレートを適用した後、この CheckBoxUncheckedChecked、および Indeterminate 状態でどのように表示されるかを次に示します。

カスタム チェックボックス テンプレート

コントロールのビジュアル構造を指定する

ControlTemplate を作成するときは、FrameworkElement オブジェクトを組み合わせて 1 つのコントロールを構築します。 ControlTemplate のルート要素として必要な FrameworkElement は 1 つだけです。 ルート要素には通常、他の FrameworkElement オブジェクトが 含まれています。 オブジェクトの組み合わせによって、コントロールのビジュアル構造が構成されます。

この XAML は、コントロールの内容が選択ボックスの下にあることを指定する CheckBoxControlTemplate を作成します。 ルート要素は Border です。 この例では、ユーザーが CheckBox を選択したことを示す X を作成するパスと、不確定状態を示す省略記号を指定します。 の不透明度パス楕円 に対して 0 に設定されているため、既定ではどちらも表示されません。

TemplateBinding は、コントロール テンプレート内のプロパティの値を、テンプレート 化されたコントロールの他の公開プロパティの値にリンクする特殊なバインドです。 TemplateBinding は、XAML の ControlTemplate 定義内でのみ使用できます。 詳細については、「TemplateBinding マークアップ拡張」 をご覧ください。

Windows 10 バージョン 1809 (SDK 17763) 以降では、TemplateBinding を使用する場所で x:Bind マークアップ拡張機能を使用できます。 詳細については、「TemplateBinding マークアップ拡張」 をご覧ください。

<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
    <Border BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Background="{TemplateBinding Background}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="25"/>
            </Grid.RowDefinitions>
            <Rectangle x:Name="NormalRectangle" Fill="Transparent" Height="20" Width="20"
                       Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                       StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
                       UseLayoutRounding="False"/>
            <!-- Create an X to indicate that the CheckBox is selected. -->
            <Path x:Name="CheckGlyph"
                  Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
                  Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                  FlowDirection="LeftToRight"
                  Height="14" Width="16" Opacity="0" Stretch="Fill"/>
            <Ellipse x:Name="IndeterminateGlyph"
                     Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                     Height="8" Width="8" Opacity="0" UseLayoutRounding="False" />
            <ContentPresenter x:Name="ContentPresenter"
                              ContentTemplate="{TemplateBinding ContentTemplate}"
                              Content="{TemplateBinding Content}"
                              Margin="{TemplateBinding Padding}" Grid.Row="1"
                              HorizontalAlignment="Center"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Grid>
    </Border>
</ControlTemplate>

コントロールの視覚的な動作を指定する

ビジュアル動作では、コントロールが特定の状態にある場合の外観を指定します。 CheckBox コントロールには、CheckedUncheckedIndeterminateの 3 つのチェック状態があります。 IsChecked プロパティの値によって CheckBox の状態が決定され、その状態によってボックスに表示される内容が決まります。

次の表に、 IsChecked の使用可能な値、 CheckBox の対応する状態、および CheckBox の外観を示します。

IsChecked の値 チェックボックス の状態 CheckBox の外観
真実 Checked "X" を含みます。
Unchecked 空。
ヌル Indeterminate 円を含みます。

VisualState オブジェクトを使用して、特定の状態にある場合のコントロールの外観を指定します。 VisualState には、ControlTemplate 内の要素の外観を変更するセッターまたはストーリーボードが含まれています。 コントロールが VisualState.Name プロパティが指定した状態になると、Setter または Storyboard のプロパティの変更が適用されます。 コントロールが状態を終了すると、変更は削除されます。 VisualState オブジェクト VisualStateGroup オブジェクト 追加します。 VisualStateGroup オブジェクト ControlTemplateのルート FrameworkElement に設定した、VisualStateManager.VisualStateGroups 添付プロパティに追加します。

この XAML は、、およびChecked状態の Indeterminate オブジェクトを示しています。 この例では、VisualStateManager.VisualStateGroups 添付プロパティを、Borderに設定します。それは ControlTemplateのルート要素です。 Checked VisualState は、(前の例で示した) という名前のパスCheckGlyphが 1 であることを指定します。 Indeterminate VisualState は、という名前の楕円IndeterminateGlyphが 1 であることを指定します。 Unchecked VisualState には SetterStoryboardがないため、CheckBox は既定の外観に戻ります。

<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
    <Border BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Background="{TemplateBinding Background}">

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CheckStates">
                <VisualState x:Name="Checked">
                    <VisualState.Setters>
                        <Setter Target="CheckGlyph.Opacity" Value="1"/>
                    </VisualState.Setters>
                    <!-- This Storyboard is equivalent to the Setter. -->
                    <!--<Storyboard>
                        <DoubleAnimation Duration="0" To="1"
                         Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Opacity"/>
                    </Storyboard>-->
                </VisualState>
                <VisualState x:Name="Unchecked"/>
                <VisualState x:Name="Indeterminate">
                    <VisualState.Setters>
                        <Setter Target="IndeterminateGlyph.Opacity" Value="1"/>
                    </VisualState.Setters>
                    <!-- This Storyboard is equivalent to the Setter. -->
                    <!--<Storyboard>
                        <DoubleAnimation Duration="0" To="1"
                         Storyboard.TargetName="IndeterminateGlyph" Storyboard.TargetProperty="Opacity"/>
                    </Storyboard>-->
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="25"/>
            </Grid.RowDefinitions>
            <Rectangle x:Name="NormalRectangle" Fill="Transparent" Height="20" Width="20"
                       Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                       StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
                       UseLayoutRounding="False"/>
            <!-- Create an X to indicate that the CheckBox is selected. -->
            <Path x:Name="CheckGlyph"
                  Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
                  Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                  FlowDirection="LeftToRight"
                  Height="14" Width="16" Opacity="0" Stretch="Fill"/>
            <Ellipse x:Name="IndeterminateGlyph"
                     Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                     Height="8" Width="8" Opacity="0" UseLayoutRounding="False" />
            <ContentPresenter x:Name="ContentPresenter"
                              ContentTemplate="{TemplateBinding ContentTemplate}"
                              Content="{TemplateBinding Content}"
                              Margin="{TemplateBinding Padding}" Grid.Row="1"
                              HorizontalAlignment="Center"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Grid>
    </Border>
</ControlTemplate>

VisualState オブジェクトの動作について理解を深めるために、CheckBoxUnchecked状態からChecked状態、Indeterminate状態、Unchecked状態に戻ったときの動作を検討します。 遷移を次に示します。

状態遷移 動作 切り替えが完了したときの CheckBox の外観
Unchecked から Checked Checkedセッター値が適用されるため、CheckGlyphは 1 です。 X が表示されます。
Checked から Indeterminate Indeterminateセッター値が適用されるため、IndeterminateGlyphは 1 です。 Checkedセッター値が削除されるため、CheckGlyphは 0 です。 円が表示されます。
Indeterminate から Unchecked Indeterminateセッター値が削除されるため、IndeterminateGlyphは 0 です。 何も表示されません。

  コントロールの表示状態を作成する方法、特に Storyboard クラスとアニメーションの種類を使用する際の詳細については、「表示状態のためのストーリーボード付きアニメーション」を参照してください。

ツールを使用してテーマを簡単に操作する

コントロールにテーマを簡単に適用するには、Microsoft Visual Studio ドキュメント アウトライン でコントロールを右クリックし、[テーマの編集] または [スタイルの編集] を選択します (右クリックするコントロールに応じて)。 その後、[ リソースの適用 ] を選択して既存のテーマを適用するか、[ 空の作成] を選択して新しいテーマを定義できます。

コントロールとアクセシビリティ

コントロールの新しいテンプレートを作成するときに、コントロールの動作や視覚的な外観を変更するだけでなく、コントロール自体の表現方法をアクセシビリティ フレームワークに変更する場合もあります。 Windows アプリでは、アクセシビリティのための Microsoft UI オートメーション フレームワークがサポートされています。 すべての既定のコントロールとそのテンプレートには、コントロールの目的と機能に適した一般的な UI オートメーション コントロールの種類とパターンがサポートされています。 これらのコントロールの種類とパターンは、支援テクノロジなどの UI オートメーション クライアントによって解釈され、これにより、より大きなアクセス可能なアプリ UI の一部としてコントロールにアクセスできるようになります。

基本的なコントロール ロジックを分離し、UI オートメーションのアーキテクチャ要件の一部を満たすために、コントロール クラスには、別のクラスであるオートメーション ピアでのアクセシビリティサポートが含まれます。 オートメーション ピアは、特定の名前付きパーツがテンプレートに存在することを想定しているため、コントロール テンプレートとの対話を行う場合があります。そのため、支援技術によるボタンのアクションの呼び出しを可能にするなどの機能が可能になります。

まったく新しいカスタム コントロールを作成するときに、新しいオートメーション ピアを作成して同じ操作を行う必要がある場合もあります。 詳細については、「カスタム オートメーション ピア の項を参照してください」。

コントロールの既定のテンプレートの詳細を確認する

XAML コントロールのスタイルとテンプレートについて説明するトピックでは、前に説明した テーマの編集 または スタイルの編集 の手法を使用した場合に表示される開始 XAML の抜粋を示しています。 各トピックでは、表示状態の名前、使用されるテーマ リソース、テンプレートを含むスタイルの完全な XAML を一覧表示します。 このトピックは、テンプレートの変更を既に開始していて、元のテンプレートの外観を確認する場合や、新しいテンプレートに必要なすべての名前付き表示状態があることを確認する場合に役立つガイダンスです。

コントロール テンプレートのテーマ リソース

XAML の例の一部の属性では、{ThemeResource} マークアップ拡張を使ったリソース参照を見かけることがあるかもしれません。 これは、1 つのコントロール テンプレートで、現在アクティブなテーマに応じて異なる値を指定できるリソースを使用できるようにする手法です。 テーマの主な目的は、システム全体に暗いテーマ、明るいテーマ、ハイ コントラスト テーマのどちらを適用するかをユーザーが選択できるようにすることであるため、これはブラシと色にとって特に重要です。 XAML リソース システムを使用するアプリでは、そのテーマに適したリソース セットを使用できます。そのため、アプリの UI のテーマの選択は、ユーザーのシステム全体のテーマの選択を反映します。

サンプル コードを取得する