如何在基于另一个样式的样式的属性模板中更改控件模板的属性

时间:2018-11-03 23:24:00

标签: xaml uwp uwp-xaml

我正在尝试为项目设置自定义样式,同时维护隐式UWP样式并维护许多隐式UWP样式属性。

在此示例中,我想保留所有默认的UWP按钮样式并设置要引用的键。这使我可以根据此默认值制作自定义样式

默认的UWP样式,其键为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>

然后,我想基于此样式创建自定义样式,并且仅更改必要的属性(这使我可以非常轻松地跟踪要更改的属性)

基于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>

我的问题是我想在模板属性中更改控件模板的属性。但是,正如您期望的那样,在上面的代码中,当我尝试将网格的CornerRadius设置为15时,这是ControlTemplate的唯一属性(即未保留任何默认样式属性)。

猜想我可能在控制模板或网格的某个地方需要另一个键参考。我最好不要完全复制并粘贴控制模板,因为以这种方式进行设置的目的是使我非常清楚要更改的属性。

非常感谢任何帮助。

谢谢

1 个答案:

答案 0 :(得分:1)

  

我的问题是我想在模板属性中更改控件模板的属性。

当您在Template中设置CustomButtonStyle属性时,将覆盖该内容。而且我不知道您为什么要基于默认按钮样式创建新的CustomButtonStyle,您可以直接使用默认样式并修改 RootGrid CornerRadius属性。

要添加CornerRadius属性,可以为按钮添加新的依赖项属性,然后使用CornerRadius标记将RootGrid绑定到 TemplateBinding 。 / p>

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

背后的代码

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));

}

用法

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

有关更多信息,您可以参考Custom dependency properties