使用Rx(Reactive Extensions)观察ObservableCollection中的特定项目

使用Rx(Reactive Extensions)观察ObservableCollection中的特定项目

问题描述:

我有一个ObservableCollection,需要为特定项目引用。如果项目不存在,我需要通过Reactive Extensions来监控它是否出现在项目中,但是在设置声明时需要一些帮助。我仍然不熟悉所有不同的Linq扩展是如何工作的,所以我不知道如何做到这一点。任何人都可以将我指向正确的方向吗?使用Rx(Reactive Extensions)观察ObservableCollection中的特定项目

为了更好地说明,我需要像下面这样:

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; 

这不完全是我的方案,但希望你能看到我想要做的事。 ObservableCollection可能不包含任何项目开始,并且属性值异步进入。我知道最后一行是不正确的,我需要在lambda类中的类PropertyChanged事件上有一个Observable ...但我仍然对如何在满足两个条件时获得该值的等待感到困惑。

添加ReactiveUI到您的项目,那么你可以使用ReactiveCollection类,从WPF的的ObservableCollection派生。然后这很容易:

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

ObservableCollection现在是一种不幸的命名选择:(这是在做Rx训练时碰到的道路 –

+0

看起来就像我需要的那样 – Random

+0

我没有意识到ReactiveUI会成为如此庞大的库。看起来不错,我只是希望在几个月前知道它,这个时候它可能不适合我的项目。所以,虽然我希望将来可以使用它,但这是“一个”的答案,我需要取消选择它作为“接受”的答案。 – Random

通用ObservableCollection与IObservable接口无关。您可以使用下列但是通过监控的Rx一个ObservableCollection的CollectionChanged事件:

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

这会给你一个通知,每当项目(S)被添加到的ObservableCollection。这些项目将是一个非通用的IList,因此我们可以将其转换为该.AsObservable上的底层SomeType和SelectMany的IEnumerable,以获取新的可观察的传入值流。最后,在订阅,你做你想要的终值(而不是使用阻塞第一次调用)什么:

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

我编辑我的问题上面更清楚。 – Random

+0

+1。一个问题 - 我有这个** _ keywaitingfor _ **出现在另一个集合中。如何在其他集合中搜索或匹配** _ itemAdded.Key _ **? –