一个属性上有多个故事板

7
我有多个故事板访问同一属性(不同时)。在一个故事板更改属性后,另一个似乎无法访问它并且什么也不会改变。我该怎么做才能解决这个问题?
示例:
<ListBox>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border Name="Border" BorderBrush="DarkGray" BorderThickness="1" Margin="3">
                            <ContentPresenter />
                            <Border.Background>
                                <SolidColorBrush />
                            </Border.Background>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Trigger.EnterActions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Background.Color" To="#3e8bff" Duration="0:0:0.1" />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </Trigger.EnterActions>
                                <Trigger.ExitActions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Background.Color" To="White" Duration="0:0:0.1" />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </Trigger.ExitActions>
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True" />
                                    <Condition Property="IsSelected" Value="False" />
                                </MultiTrigger.Conditions>
                                <MultiTrigger.EnterActions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Background.Color" To="Orange" Duration="0:0:0.1" />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </MultiTrigger.EnterActions>
                                <MultiTrigger.ExitActions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Background.Color" To="White" Duration="0:0:0.1" />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </MultiTrigger.ExitActions>
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.Items>
        <sys:String>hey</sys:String>
        <sys:String>du</sys:String>
        <sys:String>dux</sys:String>
        <sys:String>duy</sys:String>
        <sys:String>dua</sys:String>
    </ListBox.Items>
</ListBox>

这是我能制作的最简单的代码示例。在您将鼠标悬停在项目上后,当您选择它时,它不会变成蓝色(尝试单击一个项目,然后使用箭头键选择项目而无需将鼠标悬停在上面)。

你所说的“另一个似乎无法访问它并且不会改变任何东西”是什么意思?你是否收到错误消息?还是出现了特定的意外行为? - Adam Robinson
更具体地说,我有一个ListBox。在ItemContainerStyle中,我为所有ListBoxItems定义了一个模板。在这里,我触发IsMouseOver和IsSelected,并为淡入/淡出效果定义了一个Storyboard。当项目被悬停时,背景应该变成橙色,当它被选中时,应该变成蓝色。我可以将一个项目悬停多次,它可以正常工作。但是如果我选择它,然后再取消选择,悬停效果就不再起作用了。如果我使用不同的属性,它仍然有效。 - eflorico
似乎与触发器的顺序有关。如果我将IsSelected触发器放在IsMouseOver触发器前面(顺便说一下,这是一个MultiTrigger,当项目被选中时不会触发),那么情况就相反了:在项目被悬停一次后,IsSelected效果不起作用。 - eflorico
2个回答

13

我有一个解决方案!!!触发器和动作的顺序很重要……答案是不要同时播放多个故事板,只需要停止其他的。

<ControlTemplate.Triggers>
    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="IsMouseOver" Value="True"/>
            <Condition Property="Selector.IsSelected" Value="False" />
        </MultiTrigger.Conditions>
        <MultiTrigger.EnterActions>
            <StopStoryboard BeginStoryboardName="SelectedBegin" />
            <StopStoryboard BeginStoryboardName="UnselectBegin" />
            <BeginStoryboard x:Name="EnterBegin" Storyboard="{StaticResource MouseEnterSb}"/>
        </MultiTrigger.EnterActions>
        <MultiTrigger.ExitActions>
            <BeginStoryboard x:Name="LeaveBegin" Storyboard="{StaticResource MouseLeaveSb}"/>
        </MultiTrigger.ExitActions>
    </MultiTrigger>
    <Trigger Property="Selector.IsSelected" Value="True">
        <Trigger.EnterActions>
            <StopStoryboard BeginStoryboardName="LeaveBegin" />
            <StopStoryboard BeginStoryboardName="EnterBegin" />
            <BeginStoryboard x:Name="SelectedBegin" Storyboard="{StaticResource SelectedSb}"/>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
            <BeginStoryboard x:Name="UnselectBegin" Storyboard="{StaticResource UnselectSb}"/>
        </Trigger.ExitActions>
    </Trigger>
</ControlTemplate.Triggers> 

哇,我发这个问题已经有一段时间了.. ;) 很酷你最终能够解决它! - eflorico

1

我已经使用以下代码复现了您的错误结果(我也被难住了):

<ListBox>
<ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <ControlTemplate.Resources>
                        <Storyboard x:Key="BorderAnimationToRed">
                            <ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Background.Color" To="Red" Duration="0:0:0.1" />
                        </Storyboard>
                        <Storyboard x:Key="BorderAnimationToBlue">
                            <ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Background.Color" To="Blue" Duration="0:0:0.1" />
                        </Storyboard>
                        <Storyboard x:Key="BorderAnimationToOrange">
                            <ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Background.Color" To="Orange" Duration="0:0:0.1" />
                        </Storyboard>
                        <Storyboard x:Key="BorderAnimationToWhite">
                            <ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Background.Color" To="White" Duration="0:0:0.1" />
                        </Storyboard>
                    </ControlTemplate.Resources>
                    <Border Name="Border" BorderBrush="DarkGray" BorderThickness="1" Margin="3">
                        <ContentPresenter />
                        <Border.Background>
                            <SolidColorBrush />
                        </Border.Background>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Trigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource BorderAnimationToOrange}"/>
                            </Trigger.EnterActions>
                            <Trigger.ExitActions>
                                <BeginStoryboard Storyboard="{StaticResource BorderAnimationToWhite}"/>
                            </Trigger.ExitActions>
                        </Trigger>
                        <Trigger Property="IsSelected" Value="True">
                            <Trigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource BorderAnimationToBlue}"/>
                            </Trigger.EnterActions>
                            <Trigger.ExitActions>
                                <BeginStoryboard Storyboard="{StaticResource BorderAnimationToWhite}"/>
                            </Trigger.ExitActions>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ListBox.ItemContainerStyle>
<ListBox.Items>
    <sys:String>hey</sys:String>
    <sys:String>du</sys:String>
    <sys:String>dux</sys:String>
    <sys:String>duy</sys:String>
    <sys:String>dua</sys:String>
</ListBox.Items>

这段代码更容易阅读,因为可视化、资源和触发器是分开声明的。也许你可以尝试使用EventTriggers来实现你的目标(使用"ListBoxItem.MouseEnter"和"ListBoxItem.MouseLeave"路由事件)。祝你好运!

我知道我刚刚创建了我想要修改两次的控件(在我的情况下这是可能的,我只是发布了一个简化的例子)。快速+脏.. - eflorico

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接