DataTrigger.EnterActions.BeginStoryboard无法开始

时间:2011-08-26 23:27:04

标签: wpf storyboard datatrigger multidatatrigger

此XAML的目的是为ListBox设置动画。

  1. Selected ListBoxItem是Zoomed X2
  2. NotSelected ListBoxItem是Zoomed X.5
  3. 当没有选择时,它们是Zoomed X1
  4. 然而,这些故事板并未按预期行事。

    (只需将此内容复制到Kaxaml或您的收藏夹XAML编辑器中)

    这里有什么明显的东西吗?

    <Page 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:sys="clr-namespace:System;assembly=mscorlib" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
      <Page.Resources>   
    
        <x:Array Type="{x:Type sys:String}" x:Key="MyData"> 
          <sys:String>One</sys:String> 
          <sys:String>Two</sys:String> 
          <sys:String>Three</sys:String> 
          <sys:String>Four</sys:String> 
          <sys:String>Five</sys:String> 
          <sys:String>Six</sys:String> 
          <sys:String>Seven</sys:String> 
          <sys:String>Eight</sys:String> 
        </x:Array> 
    
      </Page.Resources> 
    
      <ListBox ItemsSource="{Binding Source={StaticResource MyData}}" Name="ListBoxA"> 
        <ListBox.ItemTemplate> 
          <DataTemplate> 
            <DataTemplate.Triggers> 
    
                <!-- selected (Grow) -->  
                <MultiDataTrigger> 
                    <MultiDataTrigger.Conditions> 
                        <Condition Value="True" Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" /> 
                        <Condition Value="1"  Binding="{Binding Path=SelectedItems.Count,  RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}}" /> 
                    </MultiDataTrigger.Conditions> 
                    <MultiDataTrigger.EnterActions> 
                        <BeginStoryboard Name="BeginStoryboardSelected">
                          <Storyboard> 
                            <ParallelTimeline> 
                                <DoubleAnimation To="2" DecelerationRatio="0.5" Duration="00:00:00.500" Storyboard.TargetName="MyTransform" Storyboard.TargetProperty="ScaleX"  /> 
                                <DoubleAnimation To="2" DecelerationRatio="0.5" Duration="00:00:00.500" Storyboard.TargetName="MyTransform" Storyboard.TargetProperty="ScaleY"  /> 
                            </ParallelTimeline> 
                          </Storyboard>
                        </BeginStoryboard>
                    </MultiDataTrigger.EnterActions> 
                </MultiDataTrigger> 
    
                <!-- none selected --> 
                <MultiDataTrigger> 
                    <MultiDataTrigger.Conditions> 
                        <Condition Value="False" Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" /> 
                        <Condition Value="0"  Binding="{Binding Path=SelectedItems.Count,  RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}}" /> 
                    </MultiDataTrigger.Conditions> 
                    <MultiDataTrigger.EnterActions> 
                        <BeginStoryboard Name="BeginStoryboardNoneSelected">
                          <Storyboard>
                            <ParallelTimeline> 
                                <DoubleAnimation To="1" DecelerationRatio="0.5" Duration="00:00:00.500" Storyboard.TargetName="MyTransform" Storyboard.TargetProperty="ScaleX"  /> 
                                <DoubleAnimation To="1" DecelerationRatio="0.5" Duration="00:00:00.500" Storyboard.TargetName="MyTransform" Storyboard.TargetProperty="ScaleY"  /> 
                            </ParallelTimeline> 
                          </Storyboard>
                        </BeginStoryboard>
                    </MultiDataTrigger.EnterActions> 
                </MultiDataTrigger>         
    
                <!-- shrink --> 
                <MultiDataTrigger> 
                    <MultiDataTrigger.Conditions> 
                        <Condition Value="False" Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" /> 
                        <Condition Value="1"  Binding="{Binding Path=SelectedItems.Count, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}}" /> 
                    </MultiDataTrigger.Conditions> 
                    <MultiDataTrigger.EnterActions>  
                        <BeginStoryboard Name="BeginStoryboardNotSelected">
                          <Storyboard>
                            <ParallelTimeline> 
                                <DoubleAnimation To=".5" DecelerationRatio="0.5" Duration="00:00:00.500" Storyboard.TargetName="MyTransform" Storyboard.TargetProperty="ScaleX"  /> 
                                <DoubleAnimation To=".5" DecelerationRatio="0.5" Duration="00:00:00.500" Storyboard.TargetName="MyTransform" Storyboard.TargetProperty="ScaleY"  /> 
                            </ParallelTimeline> 
                          </Storyboard>
                        </BeginStoryboard>
                    </MultiDataTrigger.EnterActions> 
                </MultiDataTrigger>         
    
            </DataTemplate.Triggers> 
    
            <!-- debug content -->
            <UniformGrid Columns="3">
              <TextBlock Text="{Binding Path=SelectedItems.Count, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, StringFormat={} SelectedItems.Count is {0}}" Margin="0,0,10,0" Foreground="Gray" />
              <TextBlock Text="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, StringFormat={} ListBoxItem.IsSelected is {0}}" Margin="0,0,10,0" Foreground="Gray" />
              <TextBlock Text="{Binding .}"> 
                <TextBlock.LayoutTransform> 
                    <ScaleTransform ScaleX="1" ScaleY="1" x:Name="MyTransform"/> 
                </TextBlock.LayoutTransform> 
              </TextBlock> 
            </UniformGrid>
    
          </DataTemplate> 
        </ListBox.ItemTemplate> 
      </ListBox> 
    
     </Page>
    

1 个答案:

答案 0 :(得分:2)

我不确定最好的解决方法,但问题是当触发器不再有效时触发器仍然需要“取消应用”它们的动画值。因此,在您的情况下,可以应用第一个触发器,但最后一个触发器的ExitAction有效地将其删除。

由于您没有指定ExitAction,它可能只执行BeginAnimation(..., null)来清除EnterAction的动画。您可以通过重新排序触发器来验证这一点,您将看到最后一个始终生效。

可以找到类似的问题here。但即便如此,它也无法按预期工作。

我可能会使用自定义控件来处理缩放动画。类似的东西:

public class AnimatedZoomDecorator : Decorator {

    public static readonly DependencyProperty ZoomLevelProperty = DependencyProperty.Register("ZoomLevel",
        typeof(double), typeof(AnimatedZoomDecorator), new FrameworkPropertyMetadata(1.0, OnZoomLevelPropertyValueChanged));

    public double ZoomLevel {
        get { return (double)this.GetValue(ZoomLevelProperty); }
        set { this.SetValue(ZoomLevelProperty, value); }
    }

    private static void OnZoomLevelPropertyValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        AnimatedZoomDecorator control = d as AnimatedZoomDecorator;
        if (control != null) {
            ScaleTransform scaleTransform = control.LayoutTransform as ScaleTransform;
            if (scaleTransform == null)
                control.LayoutTransform = scaleTransform = new ScaleTransform();

            DoubleAnimation animation = new DoubleAnimation() {
                To = control.ZoomLevel,
                DecelerationRatio = 0.5,
                Duration = new Duration(TimeSpan .FromMilliseconds(500)),
            };

            scaleTransform.BeginAnimation(ScaleTransform.ScaleXProperty, animation);
            scaleTransform.BeginAnimation(ScaleTransform.ScaleYProperty, animation);
        }
    }

}

然后可以这样使用:

<DataTemplate>
    <local:AnimatedZoomDecorator x:Name="zoom">
        <TextBlock Text="{Binding .}" />
    </local:AnimatedZoomDecorator>

    <DataTemplate.Triggers>

        <!-- shrink -->
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Value="False"
                        Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" />
                <Condition Value="1"
                        Binding="{Binding Path=SelectedItems.Count, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}}" />
            </MultiDataTrigger.Conditions>
            <Setter TargetName="zoom" Property="ZoomLevel" Value="0.5" />
        </MultiDataTrigger>

        <!-- selected (Grow) -->
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Value="True"
                        Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" />
                <Condition Value="1"
                        Binding="{Binding Path=SelectedItems.Count,  RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}}" />
            </MultiDataTrigger.Conditions>
            <Setter TargetName="zoom" Property="ZoomLevel" Value="2" />
        </MultiDataTrigger>

    </DataTemplate.Triggers>
</DataTemplate>