.Add触发RoutedEvent =“ Loaded”,但.Insert不会

时间:2019-05-25 01:26:22

标签: c# wpf

当我通过绑定到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");

1 个答案:

答案 0 :(得分:1)

看到这种差异的原因是因为模板控件在ListBox中的重用方式。正是ui控件被加载驱动当前的动画,如果您插入,它们已经被加载。

不幸的是,datacontextchanged不是路由事件,因此您需要某种行为或使用某种行为来启动动画。

我建议您改用数据触发。

将bool“ IsLoading”公共属性添加到任何行视图模型。

在需要加载动画时将其设置为true。

使用基于IsLoading = true的数据触发代替事件触发。

在行视图模型中将async方法与await Task.Delay(2000)一起使用,以在插入(或添加)视图模型后一两秒钟将其设置为false。

数据触发方法的好处是,当您最初显示20个条目时,您可以选择哪些(如果有)进行动画处理。