2011-08-26 89 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

謝謝,你當然解釋了這個問題。 –