業務のためのC#・C言語・C++学習

主にC#の文法やWPF周りのアウトプットに利用してます。

【C#-WPF】ControlTemplateでコントロールの外観をカスタマイズするには

WPFにおいてControlTemplate(コントロールテンプレート)とは、コントロールの外観を自由にカスタマイズする機能のことである。コントロールテンプレートが利用できるコントロールにはLabel、Window、Frame、Button、CheckBox、ComboBox、RadioButtonなどがあり既存の外観を変更したい場合に利用する。

ControlTemplateのざっとしたイメージ

コントロールのContentを除いた部分を対象とし、ControlTemplateでカスタマイズする。

Content部分を変更したい場合はこちらを参照 gaishiengineer.hatenablog.com

CheckBoxを用いたコントロールテンプレートの例

CheckBoxの外観をカスタマイズするにあたり、リソース内にControlTemplateを配置しControlTemplateに表現したい外観をXAMLで記述していく。

コーディングの概略

サンプルコード

CheckBoxの外観を変更した例を示す。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="CheckBox">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="CheckBox">
                        
                        <Grid Margin="0,0,-25.2,0">
                        <BulletDecorator Background="Gray">
                            <Border x:Name="Border" Width="13" Height="13" CornerRadius="0" BorderThickness="1" Background="Red">
                                    <Path Width="7" 
                                          Height="7" 
                                          x:Name="CheckMark" 
                                          Stroke="Yellow" StrokeThickness="2" 
                                          Data="M 0 0 L 7 7 M 0 7 L 7 0" />
                                </Border>
                        </BulletDecorator >
                        <ContentPresenter HorizontalAlignment="Right" VerticalAlignment="Center" />
                            </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" Value="false">
                                <Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <CheckBox Margin="129,115,296.4,153.8" Content="Content"/>
    </Grid>
</Window>

出力結果 サンプルの解説
CheckBoxの外観設定箇所やチェックマークの出現タイミング=トリガー箇所を示す。
コントロールテンプレートは最も一般的とされているリソース内で使用します。
リソースの詳細はこちらを参照してください。 gaishiengineer.hatenablog.com

赤枠、グレイ枠、黄色×マークの外観をそれぞれリソース内で設定。
CheckBoxの外観を設定しただけでは、チェックマークは機能しない。ここでは黄色×マークの外観の変数名をx:Name="CheckMark" とし、ControlTemplate.Triggersを設定することでチェックマーク機能を起動させる。
また、文字と出力するContentにはContentPresenterの記述が必要である。

TextBoxを用いたコントロールテンプレートの例

ControlTemplateで内のTargetTypeでTextBoxを指定。
形と背景色を指定。

<Window x:Class="ControlTemplate2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ControlTemplate2"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
            <ControlTemplate x:Key="textBoxTemplate" TargetType="TextBox">
                <Grid>
                    <Rectangle Fill="AliceBlue"/>
                    <Ellipse Fill="Red"/>
                </Grid>
            </ControlTemplate>
    </Window.Resources>

    <Grid>
        <TextBox Text="AAAAAAA" Template="{StaticResource textBoxTemplate}"/>
    </Grid>
</Window>

出力結果 Window.Resources内でコントロールテンプレートをx:Key属性を用い定義。
利用者側のTextBoxでは、Template="{StaticResource textBoxTemplate}"を用いリソースて定義したテンプレートを反映する。

x:Key属性を用いずStyleを用いる場合 TargetTypeのみの設定であれば全てのTextBoxにリソースで設定した外観が反映される。

<Window x:Class="ControlTemplate1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ControlTemplate1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>

        <Style TargetType="TextBox">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TextBox">
                        <Grid>
                            <Rectangle Fill="AliceBlue"/>
                            <Ellipse Fill="Red"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Window.Resources>
    <Grid>
        <TextBox Text="AAAAAAA"/>
    </Grid>
</Window>