我正在学习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>
字符串
正如你所看到的,这种风格应该做几件事:
- 应用默认的
FontFamily
、MinHeight
和Background
; - 使用
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并编辑我需要的属性,但我想要更干净的东西(这样,如果我改变动画部分,它将应用于所有派生样式)。
任何帮助都是真正的赞赏。
1条答案
按热度按时间lxkprmvk1#
主要的错误是对元素模板的逻辑及其与样式的交互的错误理解。
1.在您的示例中,主Border显示边框,但它有一个“硬”指定值:
<Border x:Name="Border" BorderThickness="0"
。至少,您需要将其更改为<Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}"
。1.“MouseOver”状态的边框颜色在模板触发器中设置:
字符串
因此,在这种状态下,绑定到父元素属性将不再起作用(其优先级低于模板触发器设置器的优先级):
<Border x:Name="Border" ... BorderBrush="{TemplateBinding BorderBrush}">
。因此,对于这种状态,为父元素的属性设置值没有意义。一次不能为一个属性设置多个值。因此,如果以后需要在使用元素的地方触发同一属性的更改,您应该想出某种机制来禁用模板中的触发器。
解决方案。
在任何情况下,您都必须创建自己的全新模板,因为此模板的逻辑不允许您按照需要处理元素。创建模板时,首先,您需要立即决定哪些元素,参数,和值,您将有常数,您将需要配置稍后在使用该元素的地方。自定义参数(如果它们不是父元素的属性)主要以两种方式设置:动态资源键(DynamicResource)或AttachedProperty(例如- Material Design包)。