此 XAML 的目的是为列表框设置动画。
- 选定的 ListBoxItem 已缩放 X2
- NotSelected ListBoxItem 缩放了 X.5
- 当没有选择任何东西时,它们是放大 X1
但是,这些 Storyboard 并未按预期运行。
(只需将整个内容复制到 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>
最佳答案
我不确定最佳解决方法,但问题是当触发器不再有效时,触发器仍需要“取消应用”它们的动画值。因此,在您的情况下,可能会应用第一个触发器,但它会被最后一个触发器的 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>
关于wpf - DataTrigger.EnterActions.BeginStoryboard 未开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7211463/