2009-10-09 3 views
7

Chodzi o to, że mam główną kontrolkę ControlTemplate, która definiuje najbardziej podstawowe rzeczy dla nowego wyglądu przycisku, który projektujemy. Ale chcę zrobić 3 inne szablony kontrolne dla tego przycisku, abyśmy mogli ustawić w nich różne kolory; ale nie chcę kopiować wklejać głównego ControlTemplate i zmieniać tam koloru, zamiast tego chcę "dziedziczyć" z tego (jak z właściwością BasedOn w Style) i zmieniać kolor w odziedziczonym ControlTemplate.Czy możliwe jest rozszerzenie ControlTemplate w taki sam sposób, jak rozszerzenie stylu w WPF?

Czy to możliwe?

Dzięki!

Odpowiedz

6

Znaleziono rozwiązanie. Nie rozszerzasz ControlTemplates, zamiast tego definiujesz wszystkie podstawowe zachowania, które chcesz, a następnie pozwalasz modyfikować je samemu stylowi lub kontrolce. Weź przykład poniżej. ControlTemplate ustawia OpacityMask i zaokrąglone rogi dla mojego prostokąta, style ustawia kolor tła dla każdego przycisku (z pomocą TemplateBinding), a tam jest moje rozwiązanie:

<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

Tak, to najlepszy sposób na zrobienie tego. Luźno, ControlTemplate powinien zdefiniować, co tam jest, Styl modyfikuje właściwości na ControlTemplate, aby określić, jak naprawdę wygląda. –

+0

Jeśli w szablonie kontrolnym są atrybuty, których nie ma kontrola, to nie działa. –

0

Alternatywnie można zdefiniować " DynamicResource "odwołanie do dowolnej właściwości zależności w szablonie kontrolnym i sprawdzenie jej wartości, biorąc pod uwagę dostępność dostępnych zasobów. Można na przykład ustawić Background = "{DynamicResource SomeBrushColorVariable}" Następnie SomeBrushColorVariable może zmienić różne typy ResourceDictionaries, które są scalone w pliku App.xaml, a nawet ustawione przez użytkownika z uwzględnieniem niektórych ustawień preferencji użytkownika lub schematu kolorów.