此XAML的目的是为ListBox设置动画。
然而,这些故事板并未按预期行事。
(只需将此内容复制到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 :(得分: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>