2009-04-26 39 views
5

Tôi có một số Listbox trong ứng dụng của mình được ràng buộc với ObservableCollections và tôi muốn tạo hoạt ảnh cho một mục nếu nó bị xóa.Hoạt hình mục bị xóa trong Listbox

Tôi đã tìm thấy câu hỏi về làm động các mục được thêm bằng cách sử dụng sự kiện FrameworkElement.Loaded, nhưng tất nhiên điều đó không hoạt động theo cùng một cách với sự kiện Đã tải xuống.

Có cách nào để thực hiện việc này theo cách có thể được sử dụng trong bảng dữ liệu không?

EDIT: Tôi đã kết nối với sự kiện CollectionChanged trong ItemsSource của mình và cố gắng áp dụng hoạt ảnh theo cách thủ công. Hiện tại có vẻ như sau:

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

Vấn đề là nó hoàn toàn không hoạt động. Mục vẫn chỉ xuất hiện. Mục vẫn ở đó khi phương thức được gọi, vì vậy nó sẽ không phát hình động trước khi nó biến mất? Hoặc tôi đang làm nó hoàn toàn sai?

Trả lời

1

Hóa ra là ngay cả khi tôi đang gây dựng sự kiện trước khi xóa sự kiện, họ cũng sẽ bị xóa ngay lập tức. Vì vậy, như tôi đã sử dụng nó như là một ngăn xếp quan sát được, tôi đã làm việc xung quanh điều này bằng cách để nguyên tố đã loại bỏ trong bộ sưu tập và loại bỏ nó sau này. như thế này:

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); 
    } 
} 

Có thể không phải là giải pháp tốt nhất, nhưng nó thực hiện công việc (ít nhất nếu tôi chỉ sử dụng nó làm ngăn xếp).

+0

Trong trường hợp của tôi, tôi có 3dparty INotifyCollectionChanged được thực thi bởi Obtics và thỉnh thoảng được thay đổi bởi sự kiện phía máy chủ ... Tôi không biết làm thế nào để animate item remove here ... Có lẽ tôi nên bọc nó bằng tùy chỉnh INotifyCollectionChanged và trì hoãn việc xóa sự kiện tùy chỉnh tăng lên hoạt hình. Nhưng điều này có thể chỉ hoạt động cho 1 mục cho mỗi sự kiện và mỗi hoạt ảnh. Hợp đồng INotifyCollectionChanged giả định rằng mọi cá thể thay đổi bộ sưu tập của họ ngay lập tức bởi các sự kiện và nếu tôi có sự chậm trễ - sự kiện tiếp theo sẽ gửi cho tôi chỉ số phần tử giả định rằng tôi đã duy trì bộ sưu tập của mình theo chỉ mục trước đó. –

1

Tôi không có quyền truy cập vào cửa sổ mã tại thời điểm này vì vậy đây là một chút ngoài cuff, nhưng bạn có thể mở rộng FrameworkElement với sự kiện Unloading không, sau đó khởi tạo từ CollectionChanged trong ObservableCollection. Nó có nghĩa là sử dụng một ObservableColleciton tùy chỉnh và lớp CustomElement tùy chỉnh nhưng nó có thể cung cấp cho bạn những gì bạn cần?

+0

Đã có sự kiện Dỡ bỏ. Nhưng dù sao nó là vô dụng cho hoạt hình, vì đây là một phương sách cuối cùng của sự tồn tại nguyên tố và không có gì để tạo hiệu ứng sau khi sự kiện này xảy ra. –

1

Bạn có thể sử dụng API Express.Commands Fluent để thay đổi trạng thái trực quan trong khi thực thi lệnh. Tôi đã đăng một ví dụ về hoạt ảnh thêm và xóa các mục trong hộp danh sách bằng cách sử dụng nó tại đây http://adammills.wordpress.com/2011/01/11/mvvm-animation-of-listbox-present-commands/

+0

Đây là giải pháp cho trường hợp khi người dùng kích hoạt lệnh này ... Trong trường hợp của tôi, tôi có INotifyCollectionChanged được triển khai bởi Obtics và thay đổi ở phía máy chủ ... Tôi không biết làm cách nào để tạo hiệu ứng động mục ở đây ... –

2

Tôi đã giải quyết điều này bằng cách thêm một thuộc tính IsRemoved vào các mục bị ràng buộc. Trình kích hoạt sự kiện trong mẫu chứa của ListViewItem sau đó được ràng buộc để phát hoạt ảnh loại bỏ khi bool này thay đổi thành true. Đồng thời, một nhiệm vụ được bắt đầu với Task.Delay (n) khớp với thời lượng của hoạt ảnh và theo dõi với việc xóa thực tế khỏi bộ sưu tập. Lưu ý rằng việc xóa này cần phải được gửi đến chuỗi sở hữu danh sách để tránh ngoại lệ cho chuỗi chéo.

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))); 
     }); 
} 
Các vấn đề liên quan