【问题标题】:Using storyboard animations for mouseover and selection in WPF ListBoxItems在 WPF ListBoxItems 中使用情节提要动画进行鼠标悬停和选择
【发布时间】:2011-03-31 07:08:45
【问题描述】:

我有一个 WPF 应用程序,它有一个列表框,我正在尝试对其应用一些鼠标悬停效果。当我使用简单的Setters 来更改鼠标悬停/选择时的背景颜色时,一切正常,但我认为如果它在状态之间进行动画处理会更好看,所以我将Setters 切换为进入/退出Storyboard s。最初一切都很好(鼠标悬停动画进出,选择动画进出),但是一旦选择了某些东西然后被取消选择,它就再也不会产生鼠标悬停效果了。

这是显示问题的最小代码示例:

<Window x:Class="WpfTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="500" Width="500">
  <Window.Resources>
    <Style x:Key="ListboxItemStyle" TargetType="{x:Type ListBoxItem}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type ListBoxItem}">
            <Border x:Name="border" BorderThickness="1" Height="50" Background="#000">
              <ContentPresenter />
            </Border>
            <ControlTemplate.Triggers>
              <MultiTrigger>
                <MultiTrigger.Conditions>
                  <Condition Property="IsMouseOver" Value="True" />
                  <Condition Property="IsSelected" Value="False" />
                </MultiTrigger.Conditions>
                <MultiTrigger.EnterActions>
                  <BeginStoryboard>
                    <Storyboard>
                      <ColorAnimation Duration="0:0:0.15" Storyboard.TargetName="border"
                          Storyboard.TargetProperty="Background.Color" To="#00F" />
                    </Storyboard>
                  </BeginStoryboard>
                </MultiTrigger.EnterActions>
                <MultiTrigger.ExitActions>
                  <BeginStoryboard>
                    <Storyboard>
                      <ColorAnimation Duration="0:0:0.3" Storyboard.TargetName="border"
                          Storyboard.TargetProperty="Background.Color" To="#008" />
                    </Storyboard>
                  </BeginStoryboard>
                </MultiTrigger.ExitActions>
              </MultiTrigger>
              <Trigger Property="IsSelected" Value="True">
                <Trigger.EnterActions>
                  <BeginStoryboard>
                    <Storyboard>
                      <ColorAnimation Duration="0:0:0.15" Storyboard.TargetName="border"
                          Storyboard.TargetProperty="Background.Color" To="#F00" />
                    </Storyboard>
                  </BeginStoryboard>
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                  <BeginStoryboard>
                    <Storyboard>
                      <ColorAnimation Duration="0:0:0.3" Storyboard.TargetName="border"
                          Storyboard.TargetProperty="Background.Color" To="#800" />
                    </Storyboard>
                  </BeginStoryboard>
                </Trigger.ExitActions>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </Window.Resources>
  <Grid>
    <ListBox x:Name="ConnectedDevicesListBox"
        ItemContainerStyle="{DynamicResource ListboxItemStyle}" >
      <ListItem/>
      <ListItem/>
      <ListItem/>
      <ListItem/>
      <ListItem/>
      <ListItem/>
      <ListItem/>
      <ListItem/>
    </ListBox>
  </Grid>
</Window>

我已将退出动画淡化为非黑色,因此您可以看到它在 IsSelected 退出情节提要之后卡住了。

有什么想法吗?

【问题讨论】:

  • 如果您交换它们,“选定”触发器将被覆盖。两者都覆盖自己

标签: .net wpf animation listbox storyboard


【解决方案1】:

情节提要的默认行为是继续将属性值设置为动画最后一帧的值。请参阅Animation Tips and Tricks,尤其是“动画后无法更改属性的值”部分。您永远不会停止情节提要,因此最终它们都在运行,并且最后声明的任何一个都将设置最终值。

您可以将 Storyboard 的 FillBehavior 设置为 Stop,以便 Storyboard 在完成后停止设置该值。我认为您会希望在 ExitActions 故事板上执行此操作,而不是在 EnterAction 故事板上执行此操作,除非您还使用普通触发器设置了背景颜色。像这样的:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsMouseOver" Value="True" />
        <Condition Property="IsSelected" Value="False" />
    </MultiTrigger.Conditions>
    <MultiTrigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Duration="0:0:0.15"
                    Storyboard.TargetName="border"
                    Storyboard.TargetProperty="Background.Color" To="#00F" />
            </Storyboard>
        </BeginStoryboard>
    </MultiTrigger.EnterActions>
    <MultiTrigger.ExitActions>
        <BeginStoryboard>
            <Storyboard FillBehavior="Stop">
                <ColorAnimation Duration="0:0:0.3"
                    Storyboard.TargetName="border"
                    Storyboard.TargetProperty="Background.Color" To="#008" />
            </Storyboard>
        </BeginStoryboard>
    </MultiTrigger.ExitActions>
</MultiTrigger>
<Trigger Property="IsSelected" Value="True">
    <Trigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Duration="0:0:0.15"
                    Storyboard.TargetName="border"
                    Storyboard.TargetProperty="Background.Color" To="#F00" />
            </Storyboard>
        </BeginStoryboard>
    </Trigger.EnterActions>
    <Trigger.ExitActions>
        <BeginStoryboard>
            <Storyboard FillBehavior="Stop">
                <ColorAnimation Duration="0:0:0.3"
                    Storyboard.TargetName="border"
                    Storyboard.TargetProperty="Background.Color" To="#800" />
            </Storyboard>
        </BeginStoryboard>
    </Trigger.ExitActions>
</Trigger>

【讨论】:

  • 谢谢你,这很有意义。我忘记了整个FillBehavior 的事情......自从我处理故事板以来已经有一段时间了(除了抱怨:为什么,哦,为什么他们不提供一个停止故事板的"StopAndHold" 选项(如Stop),但是保持最终状态(如HoldEnd)并将其设为默认值?)。
猜你喜欢
  • 2012-11-09
  • 2018-09-23
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
  • 2016-03-06
  • 2012-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多