wpf - MouseOver和MouseDown上的动画按钮

标签 wpf xaml animation

我在WPF中为标准按钮制作自己的ControlTemplate。我想在用户将鼠标悬停在按钮上时以及在用户按下按钮(变为另一种颜色)时更改按钮的背景。这似乎是一种常见的行为,但我无法使其正常工作。

我的模板由内部带有图像的边框组成。我要设置动画的边框的背景色(实际上是渐变色)。我的模板中有触发器可以激事件画( Storyboard)。

MouseOver/Out工作正常。当我按下按钮时会发生我的问题。 Press动画按预期方式运行,Release动画也是如此。但是之后,MouseOut将永远无法运行。该按钮卡在MouseOver状态。

我究竟做错了什么?

<ControlTemplate TargetType="{x:Type Button}">
    <ControlTemplate.Resources>
        <Storyboard x:Key="MouseOverAnimation">
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" Storyboard.TargetProperty="Color" To="#ffefefff" Duration="0:0:0.2" />
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" Storyboard.TargetProperty="Color" To="#ffc7c7ff" Duration="0:0:0.2" />
        </Storyboard>
        <Storyboard x:Key="MouseOutAnimation">
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" Storyboard.TargetProperty="Color" To="#ffeeeeee" Duration="0:0:0.2" />
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" Storyboard.TargetProperty="Color" To="#ffcccccc" Duration="0:0:0.2" />
        </Storyboard>
        <Storyboard x:Key="MouseDownAnimation">
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" Storyboard.TargetProperty="Color" To="#ffc7c7ff" Duration="0:0:0.1" />
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" Storyboard.TargetProperty="Color" To="#ff9a9aff" Duration="0:0:0.1" />
        </Storyboard>
        <Storyboard x:Key="MouseUpAnimation">
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" Storyboard.TargetProperty="Color" To="#ffefefff" Duration="0:0:0.1" />
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" Storyboard.TargetProperty="Color" To="#ffc7c7ff" Duration="0:0:0.1" />
        </Storyboard>
    </ControlTemplate.Resources>


    <Border x:Name="ButtonBorder" CornerRadius="0" BorderBrush="#55aaaaaa" BorderThickness="1" Width="23" Height="22">
        <Border.Background>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                <GradientBrush.GradientStops>
                    <GradientStop x:Name="ButtonBorderGradientStop1" Color="#ffeeeeee" Offset="0.0" />
                    <GradientStop x:Name="ButtonBorderGradientStop2" Color="#ffcccccc" Offset="1.0" />
                </GradientBrush.GradientStops>
            </LinearGradientBrush>
        </Border.Background>
        <Image x:Name="ButtonIcon" Source="icons/searchicon_bw.png" Width="16" Height="16" />
    </Border>


    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource MouseOverAnimation}" />
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource MouseOutAnimation}" />
            </Trigger.ExitActions>
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource MouseDownAnimation}" />
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource MouseUpAnimation}" />
            </Trigger.ExitActions>
        </Trigger>
    </ControlTemplate.Triggers> 
</ControlTemplate>

最佳答案

动画具有一个名为 FillBehavior 的属性,默认值为 HoldEnd

在完成MouseUp动画后,该值将保留阻止鼠标移出动画正确显示的值。鼠标移出动画实际上确实可以运行,但是被鼠标移入动画覆盖。如果翻转触发器的顺序,将IsPressed放在第一位,则可以看到IsMouseOver动画覆盖了所有IsPressed动画。

您可以将 FillBehavior 设置为停止,以使动画在完成后停止覆盖该属性。

在您的情况下,将FillBehavior设置为在MouseOutAnimation和MouseUpAnimation上停止就可以了。

(在此示例中,在 Storyboard 上进行设置,因此它适用于所有包含的动画。)

<ControlTemplate.Resources> 
    <Storyboard x:Key="MouseOverAnimation" Storyboard.TargetProperty="Color"> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" To="#ffefefff" Duration="0:0:0.2" /> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" To="#ffc7c7ff" Duration="0:0:0.2" /> 
    </Storyboard> 
    <Storyboard x:Key="MouseOutAnimation" Storyboard.TargetProperty="Color"
                FillBehavior="Stop"> <!-- <=================== -->
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" To="#ffeeeeee" Duration="0:0:0.2" /> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" To="#ffcccccc" Duration="0:0:0.2" /> 
    </Storyboard> 
    <Storyboard x:Key="MouseDownAnimation" Storyboard.TargetProperty="Color"> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" To="#ffc7c7ff" Duration="0:0:0.1" /> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" To="#ff9a9aff" Duration="0:0:0.1" /> 
    </Storyboard> 
    <Storyboard x:Key="MouseUpAnimation" Storyboard.TargetProperty="Color"
                FillBehavior="Stop">  <!-- <=================== -->
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" To="#ffefefff" Duration="0:0:0.1" /> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" To="#ffc7c7ff" Duration="0:0:0.1" /> 
    </Storyboard> 
</ControlTemplate.Resources>

您可以在MSDN文章Animt Overview中的What Happens After an Animation Ends?下找到有关FillBehavior的更多信息。

关于wpf - MouseOver和MouseDown上的动画按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2432790/

相关文章:

javascript - 使用javascript减少背景位置css

swift - 如何以编程方式滚动时更新 UITableview 标题高度

c# - 在 Microsoft Surface 上禁用波纹反馈

c# - XAML 属性元素

algorithm - 按元素数量设置行和列定义

c# - WPF 从 DataTrigger 调用方法

WPF,Prism v2,模式对话框中的区域,在代码后面添加区域

c# - 在另一个线程 wpf 上创建 UI 重元素

wpf - 如何使 WPF 形状完全填充

c# - 使用 System.Windows.Media.Animation 移动按钮动画