【问题标题】:Multiple storyboards on one property一个属性上的多个故事板
【发布时间】:2010-10-22 07:34:47
【问题描述】:

我有多个故事板访问同一个属性(不是同时)。在一个故事板更改属性后,另一个故事板似乎无法访问它并且没有更改任何内容。我该怎么办?

示例:

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

这是我能做的最小的示例代码。悬停一个项目后,它在被选中时不会变成蓝色(尝试单击一个项目,然后使用箭头键选择项目而不悬停它们)。

【问题讨论】:

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

标签: c# wpf xaml animation storyboard


【解决方案1】:

我有办法!!!触发器和动作顺序确实很重要...答案是不要同时播放多个故事板,只需停止其他故事板。

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

【讨论】:

  • 哇。自从我发布这个问题以来已经很久了.. ;) 很酷,你终于可以弄清楚了!
【解决方案2】:

我已经能够使用以下代码重现您的错误结果(我也很难过):

<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”路由事件)。祝你好运!

【讨论】:

  • 我知道刚刚创建了我想修改两次的控件(这在我的情况下是可能的,我只是发布了一个简化的示例)。快+脏..
猜你喜欢
  • 2018-07-12
  • 2012-09-30
  • 2013-09-17
  • 1970-01-01
  • 2014-11-13
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多