2011-08-31 11 views
10

Tôi có một ObservableCollection mà tôi cần tham chiếu cho một mục cụ thể. Nếu mặt hàng không có ở đó, tôi cần theo dõi nó thông qua Tiện ích mở rộng phản ứng nếu/khi các mục xuất hiện, nhưng cần trợ giúp trong việc thiết lập câu lệnh. Tôi vẫn chưa quen với cách tất cả các phần mở rộng Linq khác nhau được dự định làm việc, vì vậy tôi không chắc chắn làm thế nào để làm điều này. ai đó có thể chỉ cho tôi phương hướng đúng không?Sử dụng Rx (Phần mở rộng phản ứng) để xem một mục cụ thể trong ObservableCollection

Để minh họa tốt hơn, tôi cần phải giống như sau:

public class myitem :INotifyPropertyChanged 
{ 
    private string _key; 
    private string _value; 

    public string key 
    { 
     get { return _key; } 
     set { _key = value; NotifyPropertyChanged("key"); } 
    } 

    public string myvalue 
    { 
     //proper getter/setter, blah, blah 
    } 
} 

ObservableCollection<myitem> _collection = mycollection; 
var x = Observable.FromEvent<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
    h => new NotifyCollectionChangedEventHandler(h), 
    h => _collection.CollectionChanged += h, 
    h => _collection.CollectionChanged -= h); 

string keywaitingfor = "thiskey"; 
string valuewaitingfor = x.Where(xx => xx.key == keywaitingfor).First().myvalue; 

Đây không phải là chính xác kịch bản của tôi, nhưng hy vọng bạn có thể thấy những gì tôi đang cố gắng để làm. ObservableCollection có thể không chứa các mục để bắt đầu, và các giá trị thuộc tính có trong asyncronously. Tôi biết dòng cuối cùng là không đúng, tôi cần phải có một quan sát trên sự kiện PropertyChanged lớp trong một lambda ... nhưng vẫn còn bối rối về làm thế nào để chỉ nhận được rằng valuewaiting cho khi cả hai điều kiện được đáp ứng.

Trả lời

8

Thêm ReactiveUI để dự án của bạn, sau đó bạn có thể sử dụng lớp ReactiveCollection, mà xuất phát từ ObservableCollection WPF của . Sau đó, điều này rất dễ dàng như bánh:

theCollection.ItemsAdded 
    .Where(x => x.Key == "Foo") 
    .Subscribe(x => Console.WriteLine("Received Item!")); 
+3

ObservableCollection là một lựa chọn đặt tên không may ngay bây giờ: (Đây là vết sưng trên đường khi thực hiện đào tạo Rx –

+0

Trông giống như những gì tôi cần. – Random

+0

Tôi đã không nhận ra ReactiveUI sẽ trở thành một thư viện rộng lớn như vậy. Tôi chỉ muốn tôi biết về nó một vài tháng trước, nó có thể không phù hợp với dự án của tôi vào thời điểm này.Vì vậy, trong khi tôi hy vọng tôi có thể sử dụng nó trong tương lai, và nó là "một" câu trả lời, tôi cần bỏ chọn nó làm câu trả lời "được chấp nhận" – Random

14

ObservableCollection chung không có gì liên quan đến giao diện IObservable. Tuy nhiên bạn có thể theo dõi sự kiện CollectionChanged của một ObservableCollection qua Rx sử dụng như sau:

ObservableCollection<SomeType> items = yourObserableCollection; 
var itemAddedObservable = Observable 
     .FromEventPattern<NotifyCollectionChangedEventArgs>(items, "CollectionChanged") 
     .Select(change => change.EventArgs.NewItems) 

này sẽ cung cấp cho bạn một thông báo mỗi khi item (s) được bổ sung vào ObservableCollection. Các mục sẽ là một IList không chung chung, vì vậy chúng tôi có thể truyền cho một IEnumerable của SomeType và SelectMany cơ bản trên đó .AsObservable để nhận luồng mới có thể quan sát được của các giá trị đến. Cuối cùng trong Theo dõi, bạn làm những gì bạn muốn với giá trị cuối cùng (thay vì sử dụng chặn cuộc gọi đầu tiên):

var filteredAddedItem = from added in itemAddedObservable 
         from itemAdded in added.OfType<SomeType>().ToObservable() 
         where itemAdded.key = keywaitingfor 
         select itemAdded; 

var sub = filteredAddedItem.Subscribe(item => Console.WriteLine("Received " + item.myvalue)); 
+0

Tôi đã chỉnh sửa câu hỏi của mình ở trên để rõ ràng hơn. – Random

+0

+1. Một câu hỏi - Tôi có ** _ keywaitingfor _ ** này trong một bộ sưu tập khác. Làm cách nào để tìm kiếm thông qua hoặc khớp với ** _ itemAdded.Key _ ** trong bộ sưu tập khác? –