Style.Trigger与Grid.Trigger

时间:2013-03-22 11:19:11

标签: wpf xaml styles

在我的代码中,我定义了两个触发器,一个Label和一个Canvas。 我的问题描述:

当光标直接穿过Label时,Style.Trigger会被激活,背景颜色会变化(变为橙色)。当光标在画布区域上运行时,Grid.Trigger会被激活并更改背景颜色(变为紫色)。到目前为止,非常好。现在是光标,在标签区域上运行(在Grid.Trigger激活之后),背景根本不会改变。 在我看来,Grid.Trigger一旦处于活动状态就会获得优先权。

<Window x:Class="Sample01.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.Resources>
        <!-- Defined Style starts here -->
        <Style x:Key="{x:Type Label}" TargetType="{x:Type Label}" >
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Trigger.Setters>
                    </Trigger.Setters>
                    <Trigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimation To="DarkOrange" Duration="0:0:0.5"
                                                Storyboard.TargetProperty="Background.Color"
                                                />
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>
                    <Trigger.ExitActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimation To="White" Duration="0:0:1"
                                                Storyboard.TargetProperty="Background.Color" />
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.ExitActions>
                </Trigger>
            </Style.Triggers>
        </Style>
        <!-- End defined Style-->
    </Grid.Resources>
    <!-- Define Trigger -->
    <Grid.Triggers>
        <EventTrigger RoutedEvent="MouseEnter"
                      SourceName="canvas">
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimation To="BlueViolet" Duration="0:0:1"
                                    Storyboard.TargetProperty="Background.Color"
                                    Storyboard.TargetName="label" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="MouseLeave"
                      SourceName="canvas">
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimation To="White" Duration="0:0:1"
                                    Storyboard.TargetProperty="Background.Color"
                                    Storyboard.TargetName="label" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Grid.Triggers>
    <Label x:Name="label" VerticalAlignment="Top" Height="100" BorderBrush="Black" BorderThickness="2" Content="LABEL"/>
    <Canvas x:Name="canvas" Height="100" VerticalAlignment="Bottom"
            IsHitTestVisible="True" 
            Background="AntiqueWhite"
            />
</Grid>

有人可以解释这种行为吗?

1 个答案:

答案 0 :(得分:3)

您正在遇到依赖项属性的值源优先顺序。常见的情况是,当您直接在元素上设置本地值时,将覆盖样式中设置的值。在这种情况下,您将动画应用于属性,该动画优先于Style中设置的任何内容(甚至是本地值)。

要让Style重新接管,您需要使动画不再适用于Label。您可以通过显式删除初始动画来完成此操作,初始动画将重置回原始状态,就像属性触发器一样:

<EventTrigger RoutedEvent="FrameworkElement.MouseEnter"
            SourceName="canvas">
    <BeginStoryboard x:Name="GridMouseover">
        <Storyboard>
            <ColorAnimation To="BlueViolet" Duration="0:0:1"
                        Storyboard.TargetProperty="Background.Color"
                        Storyboard.TargetName="label" />
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="FrameworkElement.MouseLeave"
            SourceName="canvas">
    <RemoveStoryboard BeginStoryboardName="GridMouseover"/>
</EventTrigger>

这样做的缺点是你将平滑的动画丢失回白色。在许多情况下,VisualStateManager是更好的选择,因为它会自动为您处理。

您可以做的另一件事是告诉故事板在完成后通过更改FillBehavior停止自我应用:

<EventTrigger RoutedEvent="FrameworkElement.MouseEnter"
            SourceName="canvas">
    <BeginStoryboard>
        <Storyboard>
            <ColorAnimation To="BlueViolet" Duration="0:0:1"
                        Storyboard.TargetProperty="Background.Color"
                        Storyboard.TargetName="label" />
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="FrameworkElement.MouseLeave"
            SourceName="canvas">
    <BeginStoryboard>
        <Storyboard FillBehavior="Stop">
            <ColorAnimation To="White" Duration="0:0:1"
                        Storyboard.TargetProperty="Background.Color"
                        Storyboard.TargetName="label" />
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>