【问题标题】:ListBoxItem Style preserve MouseOver and Selected StyleListBoxItem 样式保留 MouseOver 和 Selected 样式
【发布时间】:2014-10-21 22:54:36
【问题描述】:

我有一个 ListBox,我想在其中显示当前状态,并以彩色 Rectangle 滑出。

当项目为Selected MouseOver 时,Recangle 应扩展,否则应缩小。

<ControlTemplate.Resources>
    <Storyboard x:Key="MoveOutStoryboard">
        <DoubleAnimation To="175"
                    Storyboard.TargetProperty="Width"
                    Storyboard.TargetName="AnimatingGrid">
            <DoubleAnimation.EasingFunction>
                <QuinticEase EasingMode="EaseOut" />
            </DoubleAnimation.EasingFunction>
        </DoubleAnimation>
        <ColorAnimation Storyboard.TargetName="ContentPresenter"
                Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)"
                To="White" />
    </Storyboard>

    <Storyboard x:Key="MoveInStoryboard">
        <DoubleAnimation To="16"
                    Storyboard.TargetProperty="Width"
                    Storyboard.TargetName="AnimatingGrid">
            <DoubleAnimation.EasingFunction>
                <QuinticEase EasingMode="EaseOut" />
            </DoubleAnimation.EasingFunction>
        </DoubleAnimation>
        <ColorAnimation Storyboard.TargetName="ContentPresenter"
                Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)"
                To="Black" />
    </Storyboard>
</ControlTemplate.Resources>

由于没有“或”多触发器,我想出了以下触发器:

<ControlTemplate.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
        <Trigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource MoveOutStoryboard}" />
        </Trigger.EnterActions>
    </Trigger>

    <Trigger Property="IsSelected" Value="True">
        <Trigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource MoveOutStoryboard}" />
        </Trigger.EnterActions>
    </Trigger>

    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="IsMouseOver" Value="False" />
            <Condition Property="IsSelected" Value="False" />
        </MultiTrigger.Conditions>

        <MultiTrigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource MoveInStoryboard}" />
        </MultiTrigger.EnterActions>
    </MultiTrigger>
</ControlTemplate.Triggers>

但不知何故,当我设置了最后一个 MultiTrigger 时,从未调用过 MoveOutStoryboard,但我不知道为什么。

感谢您的帮助。

【问题讨论】:

  • 这两个故事板动画相同的属性?在激活新的故事板之前尝试停止活动的故事板以访问动画属性。
  • 分享一些MoveOutStoryboard & MoveInStoryboard的示例代码
  • 我将情节提要添加到我的问题中。据我了解,最后一个触发器激活的 MoveInStorybard 应该覆盖以前的动画。

标签: wpf xaml triggers storyboard multitrigger


【解决方案1】:

因为除非由同一个触发器启动,否则另一个动画无法控制属性,所以试试这个

            <Trigger Property="IsMouseOver"
                     Value="True">
                <Trigger.EnterActions>
                    <BeginStoryboard Storyboard="{StaticResource MoveOutStoryboard}" />
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <BeginStoryboard Storyboard="{StaticResource MoveInStoryboard}" />
                </Trigger.ExitActions>
            </Trigger>
            <Trigger Property="IsSelected"
                     Value="True">
                <Trigger.EnterActions>
                    <BeginStoryboard Storyboard="{StaticResource MoveOutStoryboard}" />
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <BeginStoryboard Storyboard="{StaticResource MoveInStoryboard}" />
                </Trigger.ExitActions>
            </Trigger>

如果您遇到鼠标悬停和 IsSelected 的问题,请使用此

            <Trigger Property="IsMouseOver"
                     Value="True">
                <Trigger.EnterActions>
                    <RemoveStoryboard BeginStoryboardName="moveIn2" />
                    <RemoveStoryboard BeginStoryboardName="moveOut2" />
                    <BeginStoryboard x:Name="moveOut1"
                                     Storyboard="{StaticResource MoveOutStoryboard}" />
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <RemoveStoryboard BeginStoryboardName="moveIn2" />
                    <RemoveStoryboard BeginStoryboardName="moveOut2" />
                    <BeginStoryboard x:Name="moveIn1"
                                     Storyboard="{StaticResource MoveInStoryboard}" />
                </Trigger.ExitActions>
            </Trigger>
            <Trigger Property="IsSelected"
                     Value="True">
                <Trigger.EnterActions>
                    <RemoveStoryboard BeginStoryboardName="moveIn1" />
                    <RemoveStoryboard BeginStoryboardName="moveOut1" />
                    <BeginStoryboard x:Name="moveOut2"
                                     Storyboard="{StaticResource MoveOutStoryboard}" />
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <RemoveStoryboard BeginStoryboardName="moveIn1" />
                    <RemoveStoryboard BeginStoryboardName="moveOut1" />
                    <BeginStoryboard x:Name="moveIn2"
                                     Storyboard="{StaticResource MoveInStoryboard}" />
                </Trigger.ExitActions>
            </Trigger>

还可以删除多触发器,这可能不是必需的,或者您可以将删除情节提要方法与您的方法结合起来,这也应该有效。


编辑

这是您使用 RemoveStoryboard 的方法,这是有效的,我也测试过

    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver"
                    Value="True">
            <Trigger.EnterActions>
                <RemoveStoryboard BeginStoryboardName="multi" />
                <RemoveStoryboard BeginStoryboardName="sel" />
                <BeginStoryboard x:Name="over"
                                    Storyboard="{StaticResource MoveOutStoryboard}" />
            </Trigger.EnterActions>
        </Trigger>

        <Trigger Property="IsSelected"
                    Value="True">
            <Trigger.EnterActions>
                <RemoveStoryboard BeginStoryboardName="multi" />
                <RemoveStoryboard BeginStoryboardName="over" />
                <BeginStoryboard x:Name="sel"
                                    Storyboard="{StaticResource MoveOutStoryboard}" />
            </Trigger.EnterActions>
        </Trigger>

        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsMouseOver"
                            Value="False" />
                <Condition Property="IsSelected"
                            Value="False" />
            </MultiTrigger.Conditions>

            <MultiTrigger.EnterActions>
                <RemoveStoryboard BeginStoryboardName="sel" />
                <RemoveStoryboard BeginStoryboardName="over" />
                <BeginStoryboard x:Name="multi"
                                    Storyboard="{StaticResource MoveInStoryboard}" />
            </MultiTrigger.EnterActions>
        </MultiTrigger>
    </ControlTemplate.Triggers>   



或者这个,但这可能是错误的,你可以在动画中看到一些快照

    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver"
                    Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard x:Name="over"
                                    Storyboard="{StaticResource MoveOutStoryboard}" />
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <RemoveStoryboard BeginStoryboardName="over" />
            </Trigger.ExitActions>
        </Trigger>

        <Trigger Property="IsSelected"
                    Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard x:Name="sel"
                                    Storyboard="{StaticResource MoveOutStoryboard}" />
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <RemoveStoryboard BeginStoryboardName="sel" />
            </Trigger.ExitActions>
        </Trigger>

        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsMouseOver"
                            Value="False" />
                <Condition Property="IsSelected"
                            Value="False" />
            </MultiTrigger.Conditions>

            <MultiTrigger.EnterActions>
                <BeginStoryboard x:Name="multi"
                                    Storyboard="{StaticResource MoveInStoryboard}" />
            </MultiTrigger.EnterActions>
            <MultiTrigger.ExitActions>
                <RemoveStoryboard BeginStoryboardName="multi" />
            </MultiTrigger.ExitActions>
        </MultiTrigger>
    </ControlTemplate.Triggers>

【讨论】:

  • 第一种方法一直有效,直到您选择和取消选择一个项目。然后它将不再显示 MouseOver 效果。第二种方法不会停留在选定状态:(
  • 您是否也尝试将删除情节提要与您使用多重触发器的方法结合起来?
【解决方案2】:

所以经过多次尝试并在 pushpraj 的帮助下,我得到了最终解决方案。也许它会帮助任何有同样问题的人:

<MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsMouseOver"
                                       Value="True" />
                                <Condition Property="IsSelected"
                                       Value="False" />
                            </MultiTrigger.Conditions>

                            <MultiTrigger.EnterActions>
                                <RemoveStoryboard BeginStoryboardName="moveIn1" />
                                <RemoveStoryboard BeginStoryboardName="moveOut2" />
                                <BeginStoryboard x:Name="moveOut1"
                                         Storyboard="{StaticResource MoveOutStoryboard}" />
                            </MultiTrigger.EnterActions>
                        </MultiTrigger>

                        <Trigger Property="IsSelected"
                             Value="True">
                            <Trigger.EnterActions>
                                <BeginStoryboard x:Name="moveOut2"
                                         Storyboard="{StaticResource MoveOutStoryboard}" />
                            </Trigger.EnterActions>
                        </Trigger>

                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsMouseOver"
                                       Value="False" />
                                <Condition Property="IsSelected"
                                       Value="False" />
                            </MultiTrigger.Conditions>

                            <MultiTrigger.EnterActions>
                                <RemoveStoryboard BeginStoryboardName="moveOut2" />
                                <BeginStoryboard x:Name="moveIn1"
                                         Storyboard="{StaticResource MoveInStoryboard}" />
                            </MultiTrigger.EnterActions>
                        </MultiTrigger>

【讨论】:

  • 很棒的发现!当您必须在不同的动画/触发器中操作相同的属性时,这些事情变得非常棘手。
猜你喜欢
  • 2011-02-05
  • 1970-01-01
  • 2015-10-23
  • 1970-01-01
  • 2022-09-28
  • 2011-07-15
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
相关资源
最近更新 更多