views:

363

answers:

2

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

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.

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

EDIT: 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?

+1  A: 

I don't have access to a code window at the moment so this is a little off the cuff, but could you extend the FrameworkElement with an Unloading event, then initiate that from CollectionChanged in an ObservableCollection. It means using a custom ObservableColleciton and custom FrameworkElement class but it could offer you what you need?

ahin4114
A: 

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).

Botz3000