在动画列表框中删除项目框中、动画、项目、列表

2023-09-04 01:37:47 作者:许你春秋

我在我的应用程序绑定到ObservableCollections一些列表框,我想动画的项目,如果它被移除。

I have some Listboxes in my app bound to ObservableCollections, and i would like to animate an item if it's being removed.

我已经发现了一个问题,有关使用FrameworkElement.Loaded事件动画添加的项目,但当然,这并不以同样的方式与卸载的事件。

I already found a question about animating added items by using the FrameworkElement.Loaded event, but of course that doesn't work the same way with the Unloaded event.

有没有办法做到这一点的,可以在一个DataTemplate中使用的方法是什么?

Is there any way to do this in a way that can be used in a datatemplate?

编辑:我已经迷上了到CollectionChanged事件在我的ItemsSource并试图手动应用动画。目前,它看起来是这样的:

I've hooked up to the CollectionChanged event in my ItemsSource and tried to apply an animation manually. Currently it looks like this:

  ListBoxItem item = stack.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem;
        item.LayoutTransform = new ScaleTransform(1, 1);

    DoubleAnimation scaleAnimation = new DoubleAnimation(); 
    scaleAnimation.From = 1; 
    scaleAnimation.To = 0; 
    scaleAnimation.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500));
    ScaleTransform transform = (ScaleTransform)item.LayoutTransform;
    transform.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);

现在的问题是,它并没有在所有的工作。该项目还只是弹出了。该项目仍然存在,当方法被调用,所以应该不是玩的动画消失之前?还是我这样做完全错误的?

The problem is, it doesn't work at all. The item still just pops away. The item is still there when the method gets called, so shouldn't it be playing the animation before it disappears? Or am i doing it completely wrong?

推荐答案

原来,我就算是引发事件之前删除他们,他们会得到即时反正删除。所以当我使用它作为一个观察的堆栈,我的工作围绕这让集合中被删除的元素,后来删除。像这样的:

It turned out that even if i was raising an event before removing them, they would get removed instantly anyway. So as i was using it as an observable stack, i worked around this by leaving the removed element in the collection and removing it later. like this:

public class ObservableStack<T> : ObservableCollection<T> 
{
    private T collapsed;
    public event EventHandler BeforePop;

    public T Peek() {
        if (collapsed != null) {
            Remove(collapsed);
            collapsed = default(T);
        }
        return this.FirstOrDefault();
    }

    public T Pop() {
        if (collapsed != null) { Remove(collapsed); }
        T result = (collapsed = this.FirstOrDefault());
        if (BeforePop != null && result != null) BeforePop(this, new EventArgs());
        return result;
    }

    public void Push(T item) {
        if (collapsed != null) {
            Remove(collapsed);
            collapsed = default(T);
        }
        Insert(0, item);
    }
}

可能不是最好的解决办法,但它的工作(至少如果我只把它当作一个堆栈)。

Might not be the best solution, but it does the job (at least if i only use it as a stack).