views:

237

answers:

1

So the thing is that I have a main ControlTemplate which defines the most basic stuff for the new button look we're designing. But I want to do 3 other control templates for this button so we can set different colors in those; but I don't want to copy paste the main ControlTemplate and change the color there, instead I want to "inherit" from that (like with the BasedOn property in Style) and change the color in the inherited ControlTemplate.

Is this possible?

Thanks!

+3  A: 

Found the solution. You don't extend ControlTemplates, instead you define all the basic behavior you want, and then you let either a style or the control itself modify it. Take the example below for instance. The ControlTemplate sets the OpacityMask and the round corners for my rectangle, the Styles sets the color of the background for each button (with help of a TemplateBinding), and there's my solution:

    <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>
Carlo
Yes, that's the best way to do it. Loosely, the ControlTemplate should define what's there, the Style modifies properties on the ControlTemplate to define what it actually looks like.
Bryan Anderson