如何为 IsEnabled 属性 上的按钮设置动画已更改?
How to animate button on IsEnabled property changed?
我目前正在资源字典中为 WPF .NET Core 3.1 中的按钮模板设置样式,我想在按钮的 IsEnabled 属性 设置为 true/false 时淡化按钮颜色。根据这个 link 看来我们可以很容易地用 Trigger.Enter/ExitActions
做到这一点。但是,我似乎无法让它工作。
我尝试了一些变化:
<Trigger Property="IsEnabled" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
Duration="0:0:0.3"
To="{StaticResource ButtonGray}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
一键触发:
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.BackgroundBrush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.BorderBrush}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.ForegroundBrush}"/>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
Duration="0:0:0.3"
To="{StaticResource ButtonGray}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
最后,我尝试了触发器在同一个触发器中同时具有 EnterActions
和 ExitActions
的地方。知道为什么这不起作用吗?
更新:整个按钮样式:
<Style TargetType="{x:Type Control}" x:Key="ControlBase">
<Setter Property="FontFamily" Value="Poppins"/>
</Style>
<!-- Gray Button Styles -->
<Color x:Key="SmallButtonGray">#BB222222</Color>
<SolidColorBrush x:Key="SmallButtonGrayBrush" Color="{StaticResource SmallButtonGray}"/>
<Color x:Key="Button.Hover.BGGray">#BB333333</Color>
<SolidColorBrush x:Key="Button.Hover.BGGrayBrush" Color="{StaticResource Button.Hover.BGGray}"/>
<Color x:Key="Button.Click.Gray">#BB888888</Color>
<SolidColorBrush x:Key="Button.Click.GrayBrush" Color="{StaticResource Button.Click.Gray}"/>
<Color x:Key="Button.Disabled.Background">#44BBBBBB</Color>
<SolidColorBrush x:Key="Button.Disabled.BackgroundBrush" Color="{StaticResource Button.Disabled.Background}"/>
<Color x:Key="Button.Disabled.Border">#FFADB2B5</Color>
<SolidColorBrush x:Key="Button.Disabled.BorderBrush" Color="{StaticResource Button.Disabled.Border}"/>
<Color x:Key="Button.Disabled.Foreground">#FF838383</Color>
<SolidColorBrush x:Key="Button.Disabled.ForegroundBrush" Color="{StaticResource Button.Disabled.Foreground}"/>
<!-- Small Button Styles -->
<Style x:Key="SmallButtonStyle" TargetType="Button" BasedOn="{StaticResource ControlBase}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="FontWeight" Value="Light" />
<Setter Property="FontSize" Value="18"/>
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="TextOptions.TextRenderingMode" Value="ClearType"/>
<Setter Property="UseLayoutRounding" Value="True"/>
<Setter Property="BorderThickness" Value="1"/>
</Style>
<!-- Page Buttons-->
<Style x:Key="GrayButtonStyle" TargetType="Button" BasedOn="{StaticResource SmallButtonStyle}">
<Setter Property="Background" Value="{StaticResource SmallButtonGrayBrush}"/>
<Setter Property="Foreground" Value="{StaticResource BGWhiteBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource FGBlackBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="false"
RenderTransformOrigin="0.5,0.5"
RenderOptions.BitmapScalingMode="HighQuality">
<ContentPresenter x:Name="contentPresenter" Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Border.RenderTransform>
<ScaleTransform/>
</Border.RenderTransform>
</Border>
<ControlTemplate.Triggers>
<!-- Button Mouse Hover Animation -->
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard >
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource Button.Hover.BGGray}"
Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
To="1.05"
Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
To="1.05"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="{StaticResource ButtonGray}"
Duration="0:0:0.4"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
To="1"
Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
To="1"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!-- Button Mouse Click Animation -->
<EventTrigger RoutedEvent="PreviewMouseDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource Button.Click.Gray}"
Duration="0:0:0.2"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
To="1"
Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
To="1"
Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="PreviewMouseUp">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource Button.Hover.BGGray}"
Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
Duration="0:0:0.1"
To="1.05"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
Duration="0:0:0.1"
To="1.05"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!-- Not Enabled -->
<Trigger Property="IsEnabled" Value="false">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
Duration="0:0:0.3"
To="{StaticResource Button.Disabled.Background}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
Duration="0:0:0.3"
To="{StaticResource SmallButtonGray}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<!-- Enabled -->
<!-- Fade back into normal colors -->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
出于调试目的,我修改了模板以在您尝试设置动画的背景 属性 中查看画笔实例的 属性 值。
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="false"
RenderTransformOrigin="0.5,0.5"
RenderOptions.BitmapScalingMode="HighQuality">
<StackPanel>
<TextBlock Text="{Binding Background.Color, ElementName=border}"/>
<TextBlock Text="{Binding Background.IsFrozen, ElementName=border}"/>
</StackPanel>
<!--<ContentPresenter x:Name="contentPresenter" Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>-->
</Border>
<ControlTemplate.Triggers>
显示了 SolidColorBrush 实例(SmallButtonGrayBrush 资源)被冻结的信息。
但是冻结的实例是不可变的。
发生这种情况是因为 SmallButtonGrayBrush 和 SmallButtonGray 资源是使用 StaticResource 检索的。
如果您使用 DynamicResource 接收资源,则实例不会冻结并且动画有效。
<!-- Gray Button Styles -->
<Color x:Key="SmallButtonGray">#BB222222</Color>
<SolidColorBrush x:Key="SmallButtonGrayBrush" Color="{DynamicResource SmallButtonGray}"/>
<!-- Page Buttons-->
<Style x:Key="GrayButtonStyle" TargetType="Button" BasedOn="{StaticResource SmallButtonStyle}">
<Setter Property="Background" Value="{DynamicResource SmallButtonGrayBrush}"/>
我目前正在资源字典中为 WPF .NET Core 3.1 中的按钮模板设置样式,我想在按钮的 IsEnabled 属性 设置为 true/false 时淡化按钮颜色。根据这个 link 看来我们可以很容易地用 Trigger.Enter/ExitActions
做到这一点。但是,我似乎无法让它工作。
我尝试了一些变化:
<Trigger Property="IsEnabled" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
Duration="0:0:0.3"
To="{StaticResource ButtonGray}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
一键触发:
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.BackgroundBrush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.BorderBrush}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.ForegroundBrush}"/>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
Duration="0:0:0.3"
To="{StaticResource ButtonGray}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
最后,我尝试了触发器在同一个触发器中同时具有 EnterActions
和 ExitActions
的地方。知道为什么这不起作用吗?
更新:整个按钮样式:
<Style TargetType="{x:Type Control}" x:Key="ControlBase">
<Setter Property="FontFamily" Value="Poppins"/>
</Style>
<!-- Gray Button Styles -->
<Color x:Key="SmallButtonGray">#BB222222</Color>
<SolidColorBrush x:Key="SmallButtonGrayBrush" Color="{StaticResource SmallButtonGray}"/>
<Color x:Key="Button.Hover.BGGray">#BB333333</Color>
<SolidColorBrush x:Key="Button.Hover.BGGrayBrush" Color="{StaticResource Button.Hover.BGGray}"/>
<Color x:Key="Button.Click.Gray">#BB888888</Color>
<SolidColorBrush x:Key="Button.Click.GrayBrush" Color="{StaticResource Button.Click.Gray}"/>
<Color x:Key="Button.Disabled.Background">#44BBBBBB</Color>
<SolidColorBrush x:Key="Button.Disabled.BackgroundBrush" Color="{StaticResource Button.Disabled.Background}"/>
<Color x:Key="Button.Disabled.Border">#FFADB2B5</Color>
<SolidColorBrush x:Key="Button.Disabled.BorderBrush" Color="{StaticResource Button.Disabled.Border}"/>
<Color x:Key="Button.Disabled.Foreground">#FF838383</Color>
<SolidColorBrush x:Key="Button.Disabled.ForegroundBrush" Color="{StaticResource Button.Disabled.Foreground}"/>
<!-- Small Button Styles -->
<Style x:Key="SmallButtonStyle" TargetType="Button" BasedOn="{StaticResource ControlBase}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="FontWeight" Value="Light" />
<Setter Property="FontSize" Value="18"/>
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="TextOptions.TextRenderingMode" Value="ClearType"/>
<Setter Property="UseLayoutRounding" Value="True"/>
<Setter Property="BorderThickness" Value="1"/>
</Style>
<!-- Page Buttons-->
<Style x:Key="GrayButtonStyle" TargetType="Button" BasedOn="{StaticResource SmallButtonStyle}">
<Setter Property="Background" Value="{StaticResource SmallButtonGrayBrush}"/>
<Setter Property="Foreground" Value="{StaticResource BGWhiteBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource FGBlackBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="false"
RenderTransformOrigin="0.5,0.5"
RenderOptions.BitmapScalingMode="HighQuality">
<ContentPresenter x:Name="contentPresenter" Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Border.RenderTransform>
<ScaleTransform/>
</Border.RenderTransform>
</Border>
<ControlTemplate.Triggers>
<!-- Button Mouse Hover Animation -->
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard >
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource Button.Hover.BGGray}"
Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
To="1.05"
Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
To="1.05"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="{StaticResource ButtonGray}"
Duration="0:0:0.4"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
To="1"
Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
To="1"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!-- Button Mouse Click Animation -->
<EventTrigger RoutedEvent="PreviewMouseDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource Button.Click.Gray}"
Duration="0:0:0.2"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
To="1"
Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
To="1"
Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="PreviewMouseUp">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource Button.Hover.BGGray}"
Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
Duration="0:0:0.1"
To="1.05"/>
<DoubleAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
Duration="0:0:0.1"
To="1.05"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!-- Not Enabled -->
<Trigger Property="IsEnabled" Value="false">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
Duration="0:0:0.3"
To="{StaticResource Button.Disabled.Background}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
Duration="0:0:0.3"
To="{StaticResource SmallButtonGray}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<!-- Enabled -->
<!-- Fade back into normal colors -->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
出于调试目的,我修改了模板以在您尝试设置动画的背景 属性 中查看画笔实例的 属性 值。
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="false"
RenderTransformOrigin="0.5,0.5"
RenderOptions.BitmapScalingMode="HighQuality">
<StackPanel>
<TextBlock Text="{Binding Background.Color, ElementName=border}"/>
<TextBlock Text="{Binding Background.IsFrozen, ElementName=border}"/>
</StackPanel>
<!--<ContentPresenter x:Name="contentPresenter" Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>-->
</Border>
<ControlTemplate.Triggers>
显示了 SolidColorBrush 实例(SmallButtonGrayBrush 资源)被冻结的信息。 但是冻结的实例是不可变的。
发生这种情况是因为 SmallButtonGrayBrush 和 SmallButtonGray 资源是使用 StaticResource 检索的。 如果您使用 DynamicResource 接收资源,则实例不会冻结并且动画有效。
<!-- Gray Button Styles -->
<Color x:Key="SmallButtonGray">#BB222222</Color>
<SolidColorBrush x:Key="SmallButtonGrayBrush" Color="{DynamicResource SmallButtonGray}"/>
<!-- Page Buttons-->
<Style x:Key="GrayButtonStyle" TargetType="Button" BasedOn="{StaticResource SmallButtonStyle}">
<Setter Property="Background" Value="{DynamicResource SmallButtonGrayBrush}"/>