开发者

Problem with conditional trigger (or animation)

I have this code:

<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}开发者_Python百科"/>
    </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>

Purpose

I'm animation a Menu. Menu elements are TextBlocks, I'm simulating a "Hover fading".

Problem

The code I posted animates the opacity once the mouse enter or leave. I have another method (code behind) that sets to "1" the opacity of the menu element once the user clicks it on the menu (and load the appropriate user control on its respective container). I guess this method is working, BUT once the MouseLeave animation start it fades the opacity again no matter if that element was selected or not (If its opacity was 1 not 0.8).

Needs

Is there a way to specify that the MouseLeave trigger fires only when the Source Opacity is not 1. Or to execute the storyboard only if the TargetProperty is not 1.

Thanks.

PS

Is there a way to prevent code duplication given that the animation storyboards are the same (for focus and for fade) and that more menus will come. I duplicate it because I need to put the TargetName and is different but I suppose there is another "cleaner" way.


This behavior is due to dependency property value precedence. I haven't found a xamlish way to do this. But with code-behind here is how:

  • Subscribe to the storyboard's completed event.
  • Look for the menuItems that has been selected and call BeginAnimation on it.
  • You can find more infomation on this 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; 
            } 
        } 
    } 
    

    I have looked for IsChecked to say if a menuItem is selected. Use your own methodology if this doesnt suit you.

For question 2 add this to resources and you can get rid of all individual triggers and duplicate storyboards:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜