条件触发器(或动画)的问题

时间:2011-06-27 10:35:52

标签: c# wpf

我有这段代码:

<UserControl.Resources>
    <Storyboard x:Key="OnMouseEnterToDocumentsMenu">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Documents">
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0.8"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="OnMouseLeaveFromDocumentsMenu">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Documents">
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0.3"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="OnMouseEnterToPeopleMenu">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="People">
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0.8"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="OnMouseLeaveFromPeopleMenu">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="People">
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0.3"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
    </Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
    <EventTrigger RoutedEvent="Mouse.MouseEnter" SourceName="Documents">
        <BeginStoryboard Storyboard="{StaticResource OnMouseEnterToDocumentsMenu}"/>
    </EventTrigger>
    <EventTrigger RoutedEvent="Mouse.MouseLeave" SourceName="Documents">
        <BeginStoryboard Storyboard="{StaticResource OnMouseLeaveFromDocumentsMenu}"/>
    </EventTrigger>
    <EventTrigger RoutedEvent="Mouse.MouseEnter" SourceName="People">
        <BeginStoryboard Storyboard="{StaticResource OnMouseEnterToPeopleMenu}"/>
    </EventTrigger>
    <EventTrigger RoutedEvent="Mouse.MouseLeave" SourceName="People">
        <BeginStoryboard Storyboard="{StaticResource OnMouseLeaveFromPeopleMenu}"/>
    </EventTrigger>
    </EventTrigger>
</UserControl.Triggers>

目的

我是动画菜单。菜单元素是TextBlocks,我正在模拟“悬停淡出”。

问题

一旦鼠标进入或离开,我发布的代码就会激活不透明度。我有另一种方法(代码隐藏),一旦用户在菜单上单击它,并在其各自的容器上加载适当的用户控件,就将菜单元素的不透明度设置为“1”。我猜这个方法有效,但是一旦MouseLeave动画开始,它会再次淡化不透明度,无论该元素是否被选中(如果它的不透明度为1而不是0.8)。

需要

有没有办法指定MouseLeave触发器仅在Source Opacity不是1时触发。或者仅在TargetProperty不是1时才执行故事板。

感谢。

PS

有没有办法防止代码重复,因为动画故事板是相同的(焦点和淡入淡出),并且会有更多菜单出现。我复制它是因为我需要放置TargetName并且不同但我认为还有另一种“更清洁”的方式。

1 个答案:

答案 0 :(得分:0)

此行为是由依赖项属性值precedence引起的。我还没有找到一种简洁的方法来做到这一点。但是代码隐藏在这里是如何:

  • 订阅故事板已完成的活动。
  • 查找已选择的menuItem并在其上调用BeginAnimation。
  • 您可以在here找到更多信息。

    private void Storyboard_Completed(object sender, EventArgs e) 
    { 
        foreach (var menuItem in this.file.Items) 
        { 
            var item = (MenuItem)menuItem; 
            if (item.IsChecked) 
            { 
                item.BeginAnimation(UIElement.OpacityProperty, null); 
                item.Opacity = 1; 
            } 
        } 
    } 
    

    我已经找过IsChecked来说明是否选择了menuItem。如果这不适合您,请使用您自己的方法。

对于问题2,将其添加到资源中,您可以摆脱所有单个触发器和重复的故事板:

        <Window.Resources> 
    <Storyboard x:Key="HoverOn"> 
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)"> 
            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.8"/> 
        </DoubleAnimationUsingKeyFrames> 
    </Storyboard> 
    <Storyboard x:Key="HoverOff" Completed="Storyboard_Completed"> 
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Opacity)"> 
            <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0.3"/> 
        </DoubleAnimationUsingKeyFrames> 
    </Storyboard> 
    <Style TargetType="{x:Type MenuItem}"> 
        <Style.Triggers> 
        <EventTrigger RoutedEvent="Mouse.MouseEnter" > 
            <BeginStoryboard Storyboard="{StaticResource HoverOn}"/> 
        </EventTrigger> 
        <EventTrigger RoutedEvent="Mouse.MouseLeave"> 
            <BeginStoryboard Storyboard="{StaticResource HoverOff}"/> 
        </EventTrigger> 
        </Style.Triggers> 
    </Style> 
</Window.Resources>