如何在DataTrigger中延迟Setter生效0.5秒?

8

我想知道是否有可能延迟datatrigger 0.5秒来更改布局。是否有简单的方法可以实现?我需要设置对象的可见性,但需要等待0.5秒。非常感谢任何建议。

<DataTemplate x:Key="ListBoxItemDataTemplate">
        <Grid x:Name="DataItem">
            <Image x:Name="IconImage" Source="{Binding XPath=@icon}" Height="16" Margin="16,0,0,0" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Left" />
            <TextBlock x:Name="ListboxIemtextBlock" Text="{Binding XPath=@name}" />
            <Image x:Name="ArrowImage" Height="10" Source="Resources/Images/arrow_collapsed_grey.png" Visibility="{Binding XPath=@state}"/>
        </Grid>
         <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}, Mode=FindAncestor}}" Value="True">
                <Setter TargetName="ListboxIemtextBlock" Property="Foreground" Value="White"/>
                <Setter TargetName="IconImage" Property="Source" Value="{Binding XPath=@iconSelected}"/>
                <Setter TargetName="IconImage" Property="Height" Value="16"/>
                <Setter TargetName="ArrowImage" Property="Source" Value="Resources/Images/arrow_collapsed_white.png"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}, Mode=FindAncestor}}" Value="True">
                <Setter TargetName="ListboxIemtextBlock" Property="Foreground" Value="#FF6dacbe"/>
            </DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBox}}, Path=SelectedItem.Attributes[retract].Value}" Value="True">      
                <Setter TargetName="ListboxIemtextBlock" Property="Visibility" Value="Hidden" /> 
                <DataTrigger.EnterActions>                     
                    <BeginStoryboard Name="StartAnimation" Storyboard="{StaticResource MakeObjectVisibleAfterHalfASecond}"/>                   
                </DataTrigger.EnterActions>                   
                <DataTrigger.ExitActions>                     
                    <RemoveStoryboard BeginStoryboardName="StartAnimation"/>                   
                </DataTrigger.ExitActions>       
            </DataTrigger> 
         </DataTemplate.Triggers></DataTemplate>

故事板:

<Storyboard x:Key="MakeObjectVisibleAfterHalfASecond" Storyboard.TargetName="ListboxIemtextBlock">         
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Duration="0" BeginTime="0:0:.5">           
            <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" />         
        </ObjectAnimationUsingKeyFrames>       
    </Storyboard> 
1个回答

17

可以使用动画来实现。涉及到的部分包括:

1)一个 ObjectAnimationUsingKeyFrames,它在目标上设置 Visibility 属性,并且具有 BeginTime0:0:.5 的延迟,使该故事板开始时延迟半秒。

2)一个 DataTrigger,检查会使对象可见的属性(在此示例中,是名为 StartCheckBox 上的 IsChecked 属性)。

3)DataTrigger.EnterActions 中的 BeginStoryboard 启动动画,并在 DataTrigger.ExitActions 中使用 RemoveStoryboard 如果绑定的属性再次更改,则将对象再次变为不可见。

这是一个简单的工作示例:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>
      <Storyboard x:Key="MakeObjectVisibleAfterHalfASecond">
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                       Duration="0"
                                       BeginTime="0:0:.5">
          <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" />
        </ObjectAnimationUsingKeyFrames>
      </Storyboard>
  </Page.Resources>
  <DockPanel>  
    <CheckBox  DockPanel.Dock="Top" 
               Margin="10"
               x:Name="Start">Check this to make the label appear</CheckBox>
    <Border BorderThickness="2" 
            BorderBrush="AliceBlue" 
            CornerRadius="5" 
            Margin="10" 
            Padding="10" 
            DockPanel.Dock="Top">
        <Label Visibility="Hidden">
          <Label.Content>This should appear a half second after the box is checked.</Label.Content>
          <Label.Style>
            <Style TargetType="Label">
              <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=Start, Path=IsChecked}" Value="True">
                  <DataTrigger.EnterActions>
                    <BeginStoryboard Name="StartAnimation" 
                                     Storyboard="{StaticResource MakeObjectVisibleAfterHalfASecond}"/>
                  </DataTrigger.EnterActions>
                  <DataTrigger.ExitActions>
                    <RemoveStoryboard BeginStoryboardName="StartAnimation"/>
                  </DataTrigger.ExitActions>
                </DataTrigger>
              </Style.Triggers>
            </Style>
          </Label.Style>
        </Label>
    </Border>
    <TextBlock/>
  </DockPanel>
</Page>

需要注意的是,您也可以通过省略BeginTime并在动画上设置Duration来实现此操作,因为这两种方式本质上都是关键帧动画。


+1,没错!完全忘记了动画 :) 这就是做法。 - Fredrik Hedblad
这是你的示例中很好的方法。我正在参考Meleak已经呈现并删除的示例。我的唯一担忧是,您从代码后台引用了XML属性“retract”,而我从XMLDataprovider生成。在我的情况下,我在VS中遇到了这个错误-“不包含'retract'的定义,也没有找到接受类型为'object'的第一个参数的扩展方法'retract'(是否缺少使用指令或程序集引用?)”,它无法找到撤回属性。有什么办法吗?再次感谢。 - vladc77
Robert,你的样例很棒。它简单可靠,谢谢你的帮助。 - vladc77
Robert,当我尝试在我的解决方案中应用这个技术时,遇到了一些困难。我想知道你是否能给予建议。我将一个Storyboard添加到资源中,并修改了现有的DataTrigger,加入了进入和退出动作。但是应用程序无法运行了。我想知道我做错了什么。我在我的问题区域中添加了新的DataTrigger。谢谢。 - vladc77
"MakeObjectVisibleAfterHalfASecond" 拼写正确。我认为在 Storyboard 中引用 x:Key="MakeObjectVisibleAfterHalfASecond" 到目标 - Storyboard.TargetName="ListboxItemtextBlock" 可能在我的情况下不正确。如果这不是问题,请给予建议。我只是认为它找不到 TargetName="ListboxItemtextBlock" 的对象。 - vladc77
显示剩余2条评论

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