DataTrigger.EnterActions.BeginStoryboard 未开始
此 XAML 的目的是为 ListBox 制作动画。
- 选定的 ListBoxItem 缩放 X2
- 未选定的 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>
The purpose of this XAML is to animate a ListBox.
- The Selected ListBoxItem is Zoomed X2
- The NotSelected ListBoxItem is Zoomed X.5
- When nothing is selected, they are Zoomed X1
However, these Storyboards are not acting as expected.
(just copy this whole thing into Kaxaml, or your fav. XAML editor)
Is there something obvious here?
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定最好的解决方法,但问题是当触发器不再有效时,触发器仍然需要“取消应用”其动画值。因此,在您的情况下,可能会应用第一个触发器,但它会被最后一个触发器的 ExitAction 有效地删除。
由于您没有指定 ExitAction,它可能只是执行
BeginAnimation(..., null)
来清除 EnterAction 的动画。您可以通过重新排序触发器来验证这一点,您将看到最后一个始终生效。您可以在此处找到类似的问题。但即使如此,它似乎也没有达到预期的效果。
我可能会使用一个自定义控件来为您处理缩放动画。类似于:
然后可以像这样使用:
I'm not sure of the best workaround, but the problem is the triggers will still need to "unapply" their animated values when the trigger is no longer valid. So in your case, the first trigger may be applied, but it is effectively removed by the ExitAction of the last trigger.
Since you don't specify an ExitAction, it probably just performs a
BeginAnimation(..., null)
to clear the EnterAction's animation. You can verify this by reordering the triggers, and you will see the last one always takes effect.A similar question can be found here. But it seems even with that, it does not work as expected.
I'd probably go with a custom control that handles the zoom animation for you. Something like:
Which could then be used like this: