当我通过绑定到ViewModel的ObservableCollection将新项添加到ListBox时,试图在View中触发动画。绑定效果很好。
动画绑定到ListBox.ItemContainer样式上的RoutedEvent“ Loaded”。当我使用.Add添加新项目时,动画仅在新项目上正确触发,但是.Add只能在ObservableCollection的末尾添加项目。我的ObservableCollection已排序,因此无法正常工作。我想我有三种选择:
1)添加项目,然后重新排序列表 2)将物品插入正确的位置 3)在XAML中对列表进行排序
我无法使选项1)正常工作,因为ObservableCollection没有.Sort()(对列表进行排序)和.OrderBy(x => x.TimeStamp)需要重新创建集合,使所有项目均触发Loaded RoutedEvent(即它们全部为动画,而我只希望新项目为动画)。我也尝试过使用.ToList()。Sort()进行排序,但这似乎可以创建一个被排序并丢弃的列表。
我无法使2)正常工作。 .Add可以正常工作,并且仅触发新项目的Loaded动画,但是将其放置在不属于该项目的列表末尾。我可以使用.Insert将项目插入正确的位置;但是,.Insert不会在新插入的项目上触发动画。
我根本无法获得3)的工作,而在线上提供的示例似乎对于单线的事情似乎是不必要的复杂。
这是我正在使用的动画代码:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform x:Name="transform" />
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="LayoutTransform.ScaleY" From="0" Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
我要插入这样的项目进行测试(插入):
var timelineItem = new TimelineItem("Test", DateTime.UtcNow);
Timeline.Insert(0, timelineItem);
OnPropertyChanged("Timeline");
我要添加这样的项目进行测试(添加):
var timelineItem = new TimelineItem("Test", DateTime.UtcNow);
Timeline.Add(timelineItem);
OnPropertyChanged("Timeline");
答案 0 :(得分:1)
看到这种差异的原因是因为模板控件在ListBox中的重用方式。正是ui控件被加载驱动当前的动画,如果您插入,它们已经被加载。
不幸的是,datacontextchanged不是路由事件,因此您需要某种行为或使用某种行为来启动动画。
我建议您改用数据触发。
将bool“ IsLoading”公共属性添加到任何行视图模型。
在需要加载动画时将其设置为true。
使用基于IsLoading = true的数据触发代替事件触发。
在行视图模型中将async方法与await Task.Delay(2000)一起使用,以在插入(或添加)视图模型后一两秒钟将其设置为false。
数据触发方法的好处是,当您最初显示20个条目时,您可以选择哪些(如果有)进行动画处理。