首页 > 解决方案 > XAML 的 MouseOver 触发器的进入/退出操作在触摸 UI 元素的边缘时无限循环

问题描述

我正在尝试使用鼠标悬停触发器在 XAML 中创建一个按钮,该触发器将其 0 边距变为 0,0,0,5 但最近当我将光标留在按钮的最边缘时发现了一个问题。开始和结束动作不断被触发,我最终得到一个无限上下的按钮。

一些附加信息:

  1. 我正在使用 Visual Studio 2017

  2. 该项目是WPF

我想我可以在 c# 中解决这个问题,如果我对退出操作应用布尔要求,仅当输入操作完成或高于默认值一个数字时才运行。同时我会这样做,但如果你们有任何特定于 xaml 的解决方案,我将非常感激,因为我想尽可能地将动画留给 xaml。

        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Trigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation 
                                            From="0"
                                            To="0.4"
                                            Duration="0:0:0.2"
                                            Storyboard.TargetProperty="Effect.Opacity"/>
                            <ThicknessAnimation 
                                            From="0"
                                            To="0,0,0,5"
                                            Duration="0:0:0.2"
                                            Storyboard.TargetProperty="Margin"/>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation 
                                            From="0.4"
                                            To="0"
                                            Duration="0:0:0.2"
                                            Storyboard.TargetProperty="Effect.Opacity"/>
                            <ThicknessAnimation 
                                            From="0,0,0,5"
                                            To="0"
                                            Duration="0:0:0.2"
                                            Storyboard.TargetProperty="Margin"/>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.ExitActions>
            </Trigger>
        </Style.Triggers>

标签: xaml

解决方案


您需要额外的容器和预留空间用于轮班。

  • 用透明网格包裹你的动画边框
  • 为边框指定名称
  • 将动画触发器移动到 ControlTemplate 级别
  • 为边框添加额外的边距,将用作向上移动的空闲空间
  • 调整 From/To ThicknessAnimation 属性以使用保留边距属性
  • 为故事板元素添加 Storyboard.TargetName="{Border}" (其中 {Border} 是实际边框名称)

完整的按钮示例

<Button Width="100" Height="50">
        <Button.Style>
            <Style TargetType="Button">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Grid Background="Transparent">
                                <Border x:Name="Border" BorderThickness="5" BorderBrush="Black" Margin="0,5,0,0" Background="Red">
                                    <Border.Style>
                                        <Style TargetType="Border">
                                            <Setter Property="Effect">
                                                <Setter.Value>
                                                    <DropShadowEffect ShadowDepth="0" BlurRadius="8" Color="#FFB0E9EF"/>
                                                </Setter.Value>
                                            </Setter>
                                        </Style>
                                    </Border.Style>
                                </Border>
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger  Property="IsMouseOver" Value="True">
                                    <Trigger.EnterActions>
                                        <BeginStoryboard >
                                            <Storyboard>
                                                <DoubleAnimation From="0" To="0.4" Duration="0:0:0.2" Storyboard.TargetName="Border" 
                                                                 Storyboard.TargetProperty="Effect.Opacity"/>
                                                <ThicknessAnimation From="0,5,0,0" To="0,0,0,5" Duration="0:0:0.2" Storyboard.TargetName="Border" 
                                                                    Storyboard.TargetProperty="Margin"/>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </Trigger.EnterActions>
                                    <Trigger.ExitActions>
                                        <BeginStoryboard>
                                            <Storyboard>
                                                <DoubleAnimation From="0.4" To="0" Duration="0:0:0.2" Storyboard.TargetName="Border" 
                                                                 Storyboard.TargetProperty="Effect.Opacity"/>
                                                <ThicknessAnimation From="0,0,0,5" To="0,5,0,0" Duration="0:0:0.2" Storyboard.TargetName="Border" 
                                                                    Storyboard.TargetProperty="Margin"/>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </Trigger.ExitActions>
                                </Trigger>

                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Button.Style>
    </Button>

推荐阅读