【问题标题】:How to delay the Setter to be in affect for 0.5 sec in DataTrigger?如何延迟 Setter 在 DataTrigger 中生效 0.5 秒?
【发布时间】:2011-05-30 03:00:35
【问题描述】:

我想知道是否可以延迟数据触发器以每秒 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> 

【问题讨论】:

    标签: wpf wpf-controls binding


    【解决方案1】:

    可以使用动画来完成。涉及的部分有:

    1) 一个ObjectAnimationUsingKeyFrames 设置目标上的Visibility 属性,使用BeginTime0:0:.5 以在情节提要开始时将其延迟半秒。

    2) 一个DataTrigger,检查其更改将使对象可见的属性(在本例中,CheckBox 上的IsChecked 属性名为Start)。

    3) DataTrigger.EnterActions 中的 BeginStoryboard 启动动画,RemoveStoryboard 中的 DataTrigger.ExitActions 如果绑定属性变回,则使对象再次不可见。

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

    <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,对!完全忘记了动画 :) 这就是这样做的方法
    • 这是加入样本的好方法。我指的是 Meleak 已经展示和删除的样本。我唯一担心的是您从我从 XMLDataprovider 生成的代码中引用了 XML 属性“retract”。就我而言,我在 VS 中收到此错误-“不包含'retract'的定义,并且找不到接受'object'类型的第一个参数的扩展方法'retract'(您是否缺少 using 指令或程序集参考?)”它找不到收回属性。可以做什么?再次感谢您。
    • 罗伯特,你的样品很棒。它简单可靠。感谢您的帮助。
    • 罗伯特,当我尝试在我的解决方案中应用它时,我遇到了应用这种技术的困难。我想知道你是否可以提供建议。我在资源中添加了一个故事板,并使用 Enter 和 Exit Actions 修改了现有的数据触发器。该应用程序将不再运行。我想知道我做错了什么。我在我的问题区域中添加了新的数据触发器。谢谢。
    • 在运行时检查输出窗口是否存在绑定错误。您发布的修改版本中至少有两个名称拼写错误;他们(可能还有更多我没有注意到的)可能是问题所在。此外,最好只测试 DataTrigger 以查看它是否正常工作 - 让它改变一些可见属性,如 Background - 在搞砸EnterActionsExitActions 之前,因为如果 DataTrigger 不是被绊倒了,这里也没有其他方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多