Как задержать сеттер на 0,5 секунды в DataTrigger? - PullRequest
8 голосов
/ 23 декабря 2010

Мне интересно, можно ли отложить датгергер, чтобы изменить макет на 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 Ответ

12 голосов
/ 24 декабря 2010

Это можно сделать с помощью анимации.К этим элементам относятся:

1) ObjectAnimationUsingKeyFrames, задающее для цели свойство Visibility, с BeginTime, равным 0:0:.5, чтобы задержать это на полсекунды, когда начинается раскадровка.1007 *

2) DataTrigger, который проверяет свойство, изменение которого сделает объект видимым (в данном случае, свойство IsChecked для CheckBox с именем Start).

3) BeginStoryboard в DataTrigger.EnterActions, который запускает анимацию, и 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 для анимации, поскольку эти два по сути то же самое с анимацией по ключевому кадру.

...