2009-10-09 5 views
7

Así que la cosa es que tengo una ControlTemplate principal que define las cosas más básicas para la nueva apariencia de botón que estamos diseñando. Pero quiero hacer otras 3 plantillas de control para este botón, así podemos establecer diferentes colores en esas; pero no quiero copiar pegar el ControlTemplate principal y cambiar el color allí, en cambio quiero "heredar" de eso (como con la propiedad BasedOn en Style) y cambiar el color en el ControlTemplate heredado.¿Es posible extender una plantilla de control de la misma forma que extiende un estilo en WPF?

¿Esto es posible?

Gracias!

Respuesta

6

Encontré la solución. No extiende Plantillas de control, en su lugar, define todo el comportamiento básico que desea, y luego permite que un estilo o el control lo modifique. Tome el ejemplo a continuación, por ejemplo. El ControlTemplate establece el OpacityMask y las esquinas redondas para mi rectángulo, los estilos establece el color del fondo para cada botón (con la ayuda de un TemplateBinding), y no es mi solución:

<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

Sí, esa es la mejor manera de hacerlo. En términos generales, ControlTemplate debe definir lo que hay allí, el Estilo modifica las propiedades en ControlTemplate para definir cómo se ve realmente. –

+0

Si hay atributos en su plantilla de control que su control no tiene, esto no funciona. –

0

Como alternativa se puede definir un " DynamicResource "hace referencia a cualquier propiedad de dependencia en su plantilla de control y hace que resuelva su valor dada la presencia de recursos disponibles. Por ejemplo, se puede establecer de fondo = "{} DynamicResource SomeBrushColorVariable" Entonces SomeBrushColorVariable puede modificarse teniendo en cuenta diferentes ResourceDictionaries que se fusionaron en su archivo App.xaml o incluso establecidos por el usuario dado un poco de ajuste de visualización de las preferencias del usuario o combinación de colores.

Cuestiones relacionadas