wpf MouseOver 和 MouseDown 上的动画按钮

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2432790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:34:10  来源:igfitidea点击:

Animate button on MouseOver and MouseDown

wpfxamlanimation

提问by haagel

I'm making my own ControlTemplate for a standard Button in WPF. I want to change the background of my button when the user hovers over the button with the mouse, but also when the user presses the button (to yet another color). This seems like a common behavior, but I can't get it to work.

我正在为 WPF 中的标准按钮制作自己的 ControlTemplate。我想在用户用鼠标悬停在按钮上时更改我的按钮的背景,而且当用户按下按钮(另一种颜色)时。这似乎是一种常见的行为,但我无法让它发挥作用。

My template consists of a Border with an Image inside. It is the background color (a gradient really) of the Border that I want to animate. I have triggers in my template that activates animations (storyboards).

我的模板由一个带图像的边框组成。这是我想要动画的边框的背景颜色(实际上是渐变)。我的模板中有触发器可以激活动画(故事板)。

The MouseOver/Out works just fine. My problem occurs when I press the button. The Press animation runs as it should, and so does the Release animation. But after this the MouseOut will never run. The button gets stuck in the MouseOver state.

MouseOver/Out 工作正常。当我按下按钮时,我的问题出现了。Press 动画按原样运行,Release 动画也是如此。但在此之后,MouseOut 将永远不会运行。按钮卡在 MouseOver 状态。

What am I doing wrong?

我究竟做错了什么?

<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>

回答by Kep Amun

Animations have a property called FillBehavior, the default value is HoldEnd.

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

After your MouseUp animation finishes, it holds the value preventing the mouse out animation from displaying properly. The mouse out animation actually does run, but is covered by the mouse up animation. If you flip the order of your triggers, putting IsPressed first, you can see that the IsMouseOver animation covers all the IsPressed animations.

MouseUp 动画完成后,它会保存阻止鼠标移出动画正确显示的值。鼠标移开动画确实运行,但被鼠标移开动画覆盖。如果您翻转触发器的顺序,将 IsPressed 放在首位,您可以看到 IsMouseOver 动画覆盖了所有 IsPressed 动画。

You can set FillBehaviorto Stopto make the animations stop covering the property when they are done.

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

In your case, setting FillBehavior to Stop on your MouseOutAnimation and MouseUpAnimation does the trick.

在您的情况下,在 MouseOutAnimation 和 MouseUpAnimation 上将 FillBehavior 设置为 Stop 可以解决问题。

(In this example set on the storyboard so it applies to all the contained animations.)

(在这个例子中,在故事板上设置,所以它适用于所有包含的动画。)

<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>

You can find more info on FillBehavior in the MSDN article Animation Overview under What Happens After an Animation Ends?.

您可以在 MSDN 文章动画概述下的动画结束后发生什么?.