2011-08-26 86 views
3

此XAML的目的是动画ListBox。DataTrigger.EnterActions.BeginStoryboard not

  1. 的选择ListBoxItem中被放大X2
  2. 的NotSelected ListBoxItem中被放大X.5
  3. 当什么也没有选择,他们是放大X1

然而,这些故事板是不作为预期。

(只复制这整个事情变成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> 
+0

我通常会尝试格式化我的StackOverflow的XAML,但在这种情况下,它如果复制/粘贴只是更容易另一个编辑器因为它太长了(而且这一切都需要制作动画)。 –

回答

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> 
+0

没有选择时,我看不到如何计算zoom = 1。 –

+0

@Jerry - 这是默认缩放,所以如果没有应用触发器,它将被重置为1.0。 – CodeNaked

+0

谢谢,你当然解释了这个问题。 –