Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to extend a ControlTemplate the same way you extend a Style in WPF?

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!

like image 671
Carlo Avatar asked Oct 09 '09 20:10

Carlo


People also ask

How do I apply multiple styles in WPF?

To apply the multiple styles as you phrase it above, the best bet is to use triggers. In future version of WPF, the VisualStateManager will be introduced which supports the visual state transition between different set of setters, triggers, and animations which could enable a broader styling scenarios.

Where is style defined in WPF?

Styles are defined in the resource dictionary and each style has a unique key identifier and a target type. Inside <style> you can see that multiple setter tags are defined for each property which will be included in the style.

What is the purpose of templates in WPF?

In WPF, you use a DataTemplate to define the visual representation of data. Basically, what you put into a DataTemplate determines what the data looks like in the rendered app.


1 Answers

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>
like image 197
Carlo Avatar answered Oct 05 '22 23:10

Carlo