XAML WPF按钮样式基于另一个样式与动画

dfddblmv  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(93)

我正在学习WPF动画。
目前我有这样的按钮样式:

<Style TargetType="Button">
    <Setter Property="FontFamily" Value="{DynamicResource DefaultFont}" />
    <Setter Property="MinHeight" Value="{DynamicResource MinHeight}" />
    <Setter Property="Background" Value="{DynamicResource C4}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid SnapsToDevicePixels="True">
                    <Border x:Name="Border" BorderThickness="0" CornerRadius="{DynamicResource Radius}" BorderBrush="{TemplateBinding BorderBrush}">
                        <Border.Background>
                            <SolidColorBrush x:Name="borderBackground" Color="{StaticResource Col5}" />
                        </Border.Background>
                        <ContentPresenter x:Name="Content" VerticalAlignment="Center" HorizontalAlignment="Center"  RecognizesAccessKey="True" />
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="BorderBrush" TargetName="Border" Value="Black" />
                        <Trigger.EnterActions>
                            <BeginStoryboard x:Name="beginStoryboard">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="borderBackground"
                                                    Storyboard.TargetProperty="Color"
                                                    To="{StaticResource Col2}"
                                                    Duration="0:0:0.2">
                                    </ColorAnimation>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <RemoveStoryboard BeginStoryboardName="beginStoryboard" />
                            <BeginStoryboard x:Name="e">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="borderBackground"
                                                    Storyboard.TargetProperty="Color"
                                                    To="{StaticResource Col5}"
                                                    Duration="0:0:0.2">
                                    </ColorAnimation>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.ExitActions>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Resources>
        <Style TargetType="Border">
            <Setter Property="CornerRadius" Value="{DynamicResource Radius}" />
        </Style>
    </Style.Resources>
</Style>

字符串
正如你所看到的,这种风格应该做几件事:

  • 应用默认的FontFamilyMinHeightBackground;
  • 使用ColorAnimation动画鼠标输入和鼠标离开效果。颜色被定义为具有名称如Col 1,Col 2等的资源。

一切都正常工作(即使我怀疑这种风格可以用一种更精确的方式重写,但我需要被指出正确的方向)。
我的问题是:我需要在这个主样式的基础上创建另一个样式,所以我写了这样的东西:

<Style TargetType="Button" x:Key="AccentOnMouseOver" BasedOn="{StaticResource {x:Type Button}}">
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="BorderBrush" Value="DarkGreen"/>
            <Setter Property="BorderThickness" Value="1" />
        </Trigger>
    </Style.Triggers>
</Style>


不幸的是,这不起作用(应用了基本样式,但没有BorderBrush颜色)。我如何用背景ColorAnimation编写基本样式,然后用另一种样式派生,添加其他Triggers
一个解决方案是复制并粘贴整个基础样式,添加一个x:Key并编辑我需要的属性,但我想要更干净的东西(这样,如果我改变动画部分,它将应用于所有派生样式)。
任何帮助都是真正的赞赏。

lxkprmvk

lxkprmvk1#

主要的错误是对元素模板的逻辑及其与样式的交互的错误理解。
1.在您的示例中,主Border显示边框,但它有一个“硬”指定值:<Border x:Name="Border" BorderThickness="0"。至少,您需要将其更改为<Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}"
1.“MouseOver”状态的边框颜色在模板触发器中设置:

<ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="BorderBrush" TargetName="Border" Value="Black" />

字符串
因此,在这种状态下,绑定到父元素属性将不再起作用(其优先级低于模板触发器设置器的优先级):<Border x:Name="Border" ... BorderBrush="{TemplateBinding BorderBrush}">。因此,对于这种状态,为父元素的属性设置值没有意义。
一次不能为一个属性设置多个值。因此,如果以后需要在使用元素的地方触发同一属性的更改,您应该想出某种机制来禁用模板中的触发器。

解决方案。

在任何情况下,您都必须创建自己的全新模板,因为此模板的逻辑不允许您按照需要处理元素。创建模板时,首先,您需要立即决定哪些元素,参数,和值,您将有常数,您将需要配置稍后在使用该元素的地方。自定义参数(如果它们不是父元素的属性)主要以两种方式设置:动态资源键(DynamicResource)或AttachedProperty(例如- Material Design包)。

相关问题