Soggy
Soggy

Reputation: 152

How to change the property of a controltemplate within the property template for a Style basedon another

I am trying to set up custom styles for a project whilst maintaining of the implicit UWP styles and maintaining a lot of the implicit UWP style properties.

In this example I want to keep all of the default UWP button styles and set a key to reference. This allows me to make a custom style based on this default

The default UWP style with key DefaultButtonStyle

<Style TargetType="Button" x:Key="DefaultButtonStyle">
        <Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
        <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
        <Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}" />
        <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
        <Setter Property="Padding" Value="8,4,8,4" />
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
        <Setter Property="FontWeight" Value="Normal" />
        <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
        <Setter Property="UseSystemFocusVisuals" Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="PointerOver">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                                        </Storyboard>
                                    </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPressed}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundDisabled}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushDisabled}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ContentPresenter x:Name="ContentPresenter"
                                          BorderBrush="{TemplateBinding BorderBrush}"
                                          BorderThickness="{TemplateBinding BorderThickness}"
                                          Content="{TemplateBinding Content}"
                                          ContentTransitions="{TemplateBinding ContentTransitions}"
                                          ContentTemplate="{TemplateBinding ContentTemplate}"
                                          Padding="{TemplateBinding Padding}"
                                          HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                          AutomationProperties.AccessibilityView="Raw"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

I am then wanting to create a custom style based on this style, and only change the properties that are necessary (this allows me to keep track of the properties I am changing very easily)

My custom style basedon the DefaultButtonStyle

        <Style TargetType="Button" x:Key="CustomButtonStyle" BasedOn="{StaticResource DefaultButtonStyle}">
        <Setter Property="Padding" Value="3,3,3,3"/>
        <Setter Property="FocusVisualMargin" Value="-3"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid CornerRadius="15">
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

My issue is that I want to change properties for the control template within the template property. However, as you would expect, in the code above when I try to set the CornerRadius of the grid to 15, this is the only property for my ControlTemplate (i.e. none of the default style properties are kept).

At a guess I probably need another key reference somewhere for my control template or grid. I would preferably not like to copy and paste the controltemple in full as the purpose of setting it up this way is to make it very obvious which properties I'm changing.

Any help much appreciated.

Thanks,

Upvotes: 2

Views: 1437

Answers (1)

Nico Zhu
Nico Zhu

Reputation: 32785

My issue is that I want to change properties for the control template within the template property.

It will be covered when you set Template property in your CustomButtonStyle. And I don't know why you make a new CustomButtonStyle based on default button style, you could use default style directly and modify RootGrid CornerRadius property.

For adding CornerRadius property, you could add new dependency property for your button then bind CornerRadius to RootGrid with TemplateBinding markup.

<Grid x:Name="RootGrid" Background="{TemplateBinding Background}" CornerRadius="{TemplateBinding MyCornerRadius}">

Code behind

public sealed class MyCustomButton : Button
{
    public MyCustomButton()
    {
        this.DefaultStyleKey = typeof(MyCustomButton);
    }
    public CornerRadius MyCornerRadius
    {
        get { return (CornerRadius)GetValue(MyCornerRadiusProperty); }
        set { SetValue(MyCornerRadiusProperty, value); }
    }

    // Using a DependencyProperty as the backing store for MyCornerRadius.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyCornerRadiusProperty =
        DependencyProperty.Register("MyCornerRadius", typeof(CornerRadius), typeof(MyCustomButton), new PropertyMetadata(0));

}

Usage

<local:MyCustomButton  Content="Hello" MyCornerRadius="15"/>

For more you could refer Custom dependency properties.

Upvotes: 2

Related Questions