かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

WPF4.5入門 その52 「コントロールテンプレート」

WPFのコントロールは、見た目を完全にカスタマイズする方法が提供されています。コントロールは、TemplateというプロパティにControlTemplateを設定することで、見た目を100%カスタマイズすることが出来るようになっています。

コントロールのTemplateの差し替え例を示します。WPFのLabelコントロールには、Windows Formと異なりClickイベントが提供されていません。ここではClick可能なLabelの実現のために、Buttonコントロールの見た目をLabelにします。

<Button Content="ラベル" Click="Button_Click">
    <Button.Template>
        <ControlTemplate TargetType="{x:Type Button}">
            <Label Content="{TemplateBinding Content}" />
        </ControlTemplate>
    </Button.Template>
</Button>

ControlTemplateは、TargetTypeにテンプレートを適用するコントロールの型を指定します。そして、ControlTemplateの中に、コントロールの見た目を定義します。このとき、TemplateBindingという特殊なBindingを使うことで、コントロールのプロパティをバインドすることが出来ます。上記の例ではButtonのContentに設定された値をLabelのContentにBindingしています。

上記のコードを実行すると以下のようになります。Buttonの見た目が完全にLabelになっていることが確認できます。クリックすると、コードビハインドに記述しているMessageBox.Show(“クリック”);が実行されます。

f:id:okazuki:20140907195155p:plain

コントロールには、そのコントロールが動作するために必要な構成要素がある場合があります。スクロールバーのバーやバーを左右に移動するためのボタンなど、見た目だけでなく、操作することが出来る要素がそれにあたります。このようなコントロールは、ControlTemplate内に、コントロールごとに決められた名前で定義する必要があります。どのように定義しているかは、MSDNにある、デフォルトのコントロールテンプレートの例を参照してください。

コントロールのスタイルとテンプレート http://msdn.microsoft.com/ja-jp/library/aa970773(v=vs.110).aspx

WPFでは、Windowもコントロールなので、以下のようなWindow向けのControlTemplateを定義して適用することで、ヘッダー部やフッター部に共通の見た目を定義することも簡単に出来ます。

<ControlTemplate x:Key="WindowTemplate" TargetType="{x:Type Window}">
    <Border Background="{TemplateBinding Background}" Padding="10">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <Grid>
                <TextBlock Text="System title" FontSize="24" />
                <Button Content="Common command" HorizontalAlignment="Right" />
            </Grid>
            
            <ContentPresenter Grid.Row="1" Margin="0, 10"/>
            
            <Grid Grid.Row="2">
                <TextBlock Text="Footer" />
            </Grid>
        </Grid>
    </Border>
</ControlTemplate>

上記のControlTemplate内で使用しているContentPresenterは、ContentControl系のコントロールのControlTemplateでContentプロパティを表示するのに使用するコントロールになります。

テンプレートを適用したWindowの例を以下に示します。

<Window x:Class="ControlTemplateSample02.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        Template="{StaticResource WindowTemplate}">
    <Grid>
        <Button Content="Window content"/>
    </Grid>
</Window>

表示すると以下のようになります。

f:id:okazuki:20140907195307p:plain

過去記事