如何为 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>

最后,我尝试了触发器在同一个触发器中同时具有 EnterActionsExitActions 的地方。知道为什么这不起作用吗?

更新:整个按钮样式:

<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}"/>