2009-10-09 10 views
7

Quindi il fatto è che ho un ControlTemplate principale che definisce le cose più basilari per il nuovo aspetto del pulsante che stiamo progettando. Ma voglio fare altri 3 modelli di controllo per questo pulsante in modo che possiamo impostare colori diversi in questi; ma non voglio copiare incolla il ControlTemplate principale e cambiare il colore lì, invece voglio "ereditare" da quello (come con la proprietà BasedOn in Style) e cambiare il colore nel ControlTemplate ereditato.È possibile estendere un ControlTemplate nello stesso modo in cui estendi uno stile in WPF?

È possibile?

Grazie!

risposta

6

Trovato la soluzione. Non estendi ControlTemplates, ma definisci tutto il comportamento di base che desideri e quindi permetti a uno stile o al controllo stesso di modificarlo. Prendi l'esempio qui sotto per esempio. Il ControlTemplate imposta l'OpacityMask e gli angoli arrotondati per il mio rettangolo, gli stili imposta il colore dello sfondo per ogni pulsante (con l'aiuto di un TemplateBinding), e c'è la mia soluzione:

<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ì, questo è il modo migliore per farlo. In modo approssimativo, il ControlTemplate dovrebbe definire cosa c'è, lo stile modifica le proprietà sul ControlTemplate per definire come effettivamente appare. –

+0

Se nel proprio modello di controllo ci sono attributi che il controllo non ha, questo non funziona. –

0

In alternativa si può definire una " DynamicResource "fa riferimento a qualsiasi proprietà di dipendenza nel modello di controllo e deve risolverlo valore dato la presenza di risorse disponibili. Ad esempio, è possibile impostare Background = "{DynamicResource SomeBrushColorVariable}" Quindi SomeBrushColorVariable può cambiare dati diversi ResourceDictionaries che vengono uniti nel file App.xaml o anche impostati dall'utente con alcune impostazioni di visualizzazione delle preferenze utente o combinazioni di colori.

Problemi correlati