[英]Animating removed item in Listbox
我的應用程序中有一些與ObservableCollections綁定的列表框,如果要刪除某個項目,我想為其設置動畫。
我已經找到了一個有關使用FrameworkElement.Loaded事件為添加的項目設置動畫的問題,但是,當然,這與Unloaded事件的工作方式不同。
有什么方法可以在數據模板中使用嗎?
編輯:我已經連接到我ItemsItemSource中的CollectionChanged事件,並嘗試手動應用動畫。 當前看起來像這樣:
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);
問題是,它根本不起作用。 該項目仍然彈出。 當調用方法時,該項目仍然存在,因此它不應該在消失之前播放動畫嗎? 還是我做的完全錯誤?
我通過在綁定項中添加IsRemoved屬性解決了此問題。 然后綁定ListViewItem容器模板中的事件觸發器,當該布爾值更改為true時,該事件觸發器將播放移除動畫。 同時,以Task.Delay(n)匹配動畫的持續時間開始Task,然后從集合中實際移除。 請注意,此刪除操作需要分派給擁有該列表的線程,以避免跨線程異常。
void Remove(MyItem item, IList<MyItem> list)
{
item.IsRemoved = true;
Task.Factory.StartNew(() =>
{
Task.Delay(ANIMATION_LENGTH_MS);
Dispatcher.Invoke(new Action(() => list.Remove(item)));
});
}
您可以使用Present.Commands Fluent API在命令執行期間更改視覺狀態。 我在此處發布了一個使用列表在動畫中添加和刪除項目的動畫示例,網址為http://adammills.wordpress.com/2011/01/11/mvvm-animation-of-listbox-present-commands/
我目前無法訪問代碼窗口,因此這有點麻煩,但是您可以通過Unloading事件擴展FrameworkElement,然后從ObservableCollection中的CollectionChanged發起該事件。 這意味着使用自定義的ObservableColleciton和自定義的FrameworkElement類,但它可以為您提供所需的內容?
事實證明,即使我在刪除事件之前發起了一個活動,它們也將立即被刪除。 因此,當我將其用作可觀察的堆棧時,我通過將已刪除的元素保留在集合中並稍后將其刪除來解決此問題。 像這樣:
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);
}
}
可能不是最好的解決方案,但是它可以完成工作(至少如果我僅將其用作堆棧)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.