2009-10-09 14 views
7

私が設計している新しいボタンの外観の最も基本的なものを定義する主なControlTemplateがあります。しかし、このボタンには3つのコントロールテンプレートを用意して、異なる色を設定することができます。主ControlTemplateをコピーしてそこに色をコピーするのではなく、代わりに(StyleのBasedOnプロパティのように)それを継承し、継承したControlTemplateの色を変更したいと思います。WPFでスタイルを拡張するのと同じ方法でControlTemplateを拡張できますか?

これは可能ですか?

ありがとうございます!

答えて

6

解決策が見つかりました。 ControlTemplatesを拡張するのではなく、必要な基本的な振る舞いをすべて定義してから、スタイルまたはコントロール自体で変更することができます。たとえば以下の例を考えてみましょう。 ControlTemplateのは、OpacityMask、私の長方形のラウンドコーナー、スタイルは(TemplateBindingのの助けを借りて)各ボタンの背景の色を設定し、私の解決策があります設定します。

<Window.Resources> 
     <ControlTemplate x:Key="BaseMainButtonTemplate" TargetType="{x:Type Button}"> 
      <Grid TextBlock.Foreground="White" TextBlock.FontFamily="Calibri"> 
       <Rectangle Stroke="#FFE8E6E6" x:Name="rectangle" RadiusX="14.5" RadiusY="14.5" Fill="{TemplateBinding Property=Background}"> <!-- This TemplateBinding takes the color set by the style and applies it to the rectangle. Doing it this way, allows the style to modify the background color --> 
        <Rectangle.OpacityMask> 
         <LinearGradientBrush EndPoint="0,1" SpreadMethod="Reflect"> 
          <GradientStop Offset="0" Color="Transparent"></GradientStop> 
          <GradientStop Offset="1" Color="Gray"></GradientStop> 
         </LinearGradientBrush> 
        </Rectangle.OpacityMask> 
       </Rectangle> 
       <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/> 
      </Grid> 
      <ControlTemplate.Triggers> 
       <!-- OpacityMask when it's Focused, Defaulted and Mouse is over --> 
       <Trigger Property="IsFocused" Value="True"/> 
       <Trigger Property="IsMouseOver" Value="True"> 
        <Setter Property="OpacityMask" TargetName="rectangle"> 
         <Setter.Value> 
          <LinearGradientBrush EndPoint="0,1" SpreadMethod="Repeat"> 
           <GradientStop Offset="1" Color="Transparent"></GradientStop> 
           <GradientStop Offset="0" Color="Gray"></GradientStop> 
          </LinearGradientBrush> 
         </Setter.Value> 
        </Setter> 
       </Trigger> 
       <!-- OpacityMask when it's pressed --> 
       <Trigger Property="IsPressed" Value="True"> 
        <Setter Property="Stroke" TargetName="rectangle"> 
         <Setter.Value> 
          <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
           <GradientStop Color="#FF223472" Offset="0"/> 
           <GradientStop Color="#FFF2F0F0" Offset="0.911"/> 
          </LinearGradientBrush> 
         </Setter.Value> 
        </Setter> 
        <Setter Property="StrokeThickness" TargetName="rectangle" Value="3"/> 
       </Trigger> 
      </ControlTemplate.Triggers> 
     </ControlTemplate> 
     <Style x:Key="BlueButtonStyle" TargetType="{x:Type Button}"> 
      <Setter Property="Background" Value="Blue" /> 
      <Setter Property="Template" Value="{StaticResource BaseMainButtonTemplate}"> 
      </Setter> 
     </Style> 
     <Style x:Key="RedButtonStyle" TargetType="{x:Type Button}"> 
      <Setter Property="Background" Value="Red" /> 
      <Setter Property="Template" Value="{StaticResource BaseMainButtonTemplate}"> 
      </Setter> 
     </Style> 
     <Style x:Key="GreenButtonStyle" TargetType="{x:Type Button}"> 
      <Setter Property="Background" Value="Green" /> 
      <Setter Property="Template" Value="{StaticResource BaseMainButtonTemplate}"> 
      </Setter> 
     </Style> 
    </Window.Resources> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 
     <StackPanel> 
      <Button Style="{StaticResource BlueButtonStyle}" Height="30" Content="Test"> 
      </Button> 
      <Button Style="{StaticResource RedButtonStyle}" Height="30" Content="Test"> 
      </Button> 
      <Button Style="{StaticResource GreenButtonStyle}" Height="30" Content="Test"> 
      </Button> 
     </StackPanel> 
    </Grid> 
+0

はい、それを行う最良の方法です。ゆるやかに、ControlTemplateはそこにあるものを定義する必要があり、Styleは実際にどのように見えるかを定義するためにControlTemplateのプロパティを変更します。 –

+0

コントロールにない属性がコントロールテンプレートにある場合、これは機能しません。 –

0

代わりに、あなたは "定義することができますDynamicResource "はコントロールテンプレート内の依存関係プロパティを参照し、利用可能なリソースがある場合はその値を解決します。 たとえば、Background = "{DynamicResource SomeBrushColorVariable}"を設定できます。 次に、SomeBrushColorVariableは、App.xamlファイルにマージされた、またはユーザーの設定によっては、設定や配色の設定によって、ユーザーが設定したResourceDictionaryを変更できます。

関連する問題