Sample2 / Templateの共有
About
Sample1では最も基本的なControlTemplateの作り方について解説しました。しかしながらSample1では、Buttonコントロールの定義の中に、そのButtonを装飾するControlTemplateを定義していました。これでは2つ以上のボタンを同じ外観に装飾したい場合に、何度も繰り返しControlTemplateを定義する必要が出てきます。XAMLもC#などのソースコードと同様に、同じ定義を繰り返して記述することは、変更に弱く、非効率な実装となります。現実的に、複数のボタンのデザインがそれぞれバラバラなことはありませんから、デザインのデータは共有されるべきです。
そこでSample2では、1つのControlTemplateを複数のコントロール(ここではButton)で共有する方法について解説します。
HowTo
外観についてはSample1と何も変化はありませんが、1つのControlTemplateしか定義されていないのがSample2の特徴です。そのControlTemplateは、UserControl.Resourcesに定義されていることを確認してください。これはUserControlの中に定義された全てのコントロールから参照することができることを意味しています(厳密には違いますが)。また、これがもしWindowであれば、Window.Resourcesであるし、GridであればGrid.Resourcesです。
定義したControlTemplateの外観に関する箇所はSample1と同様ですが、それ以外の箇所に1つだけ変更点があります。それはx:Keyが設定されていることです。これは、このContoleTemplateを参照する場合に必要とする名前で、XAMLの中で一意に定義される必要があります。つまり、C#などのプログラムソースコードにおける、変数名と同様の働きをします。
<UserControl.Resources> <ControlTemplate TargetType="Button" x:Key="ButtonTemplate"> <Border Background="Blue" CornerRadius="10" Padding="10"> <TextBlock Text="Hello Template" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left"/> </Border> </ControlTemplate> </UserControl.Resources> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <Button Content="Button" Height="50" Width="200" Template="{StaticResource ButtonTemplate}" /> <Button Content="Button" Height="50" Width="200" Template="{StaticResource ButtonTemplate}" Margin="0,10,0,0" /> </StackPanel>
Buttonが定義したControlTemplateを利用する場合には、Templateプロパティを設定します。XAMLを確認するとわかるように、{StaticResource Templateの名前}となっています。これは"変更されない静的なリソースから、この名前のリソースを参照する"という記述です。ここではTemplateの名前はx:Keyによって"ButtonTemplate"と名付けたので、そのままButtonTemplateと記述しています。
これでSample2は終わりです。StaticResourceなどの記述方法は、WPFの得意とするBinding/バインディングを利用しているユーザにとっては障害となりませんが、良く理解していない初心者にとっては最初の関門です。こう書くものだと覚えてしまうのが良いと思います。
異なる名前(x:Key)を持たControlTemplateを複数定義することで複数の装飾方法を使い分けることもできます。