一个集合的观察者

时间:2011-01-18 08:21:03

标签: c# system.reactive

我正在使用.net 4上的Rx框架中的第一步。 我正在尝试观察像List<int>Dictionary<x,x>这样的集合。 当一个项目被添加到集合中时,它将在控制台中将其写为ToString()

任何想法?或一些代码示例 谢谢

3 个答案:

答案 0 :(得分:11)

List<T>Dictionary<TKey, TValue>不可观察(当它们发生变化时它们不会引发事件),因此Rx没有任何东西可以挂钩。

对于List,您可以使用ObservableCollection<T>,但是您需要将其事件包装起来以便从Rx中使用它。以下是使用扩展方法的示例:

public static class ObservableCollectionExtensions
{
    public static IObservable<IEvent<NotifyCollectionChangedEventArgs>> 
        GetObservableChanges<T>(this ObservableCollection<T> collection)
    {
        return Observable.FromEvent<
            NotifyCollectionChangedEventHandler, NotifyCollectionChangedArgs>(
                h => new NotifyCollectionChangedEventHandler(h),
                h => collection.CollectionChanged += h,
                h => collection.CollectionChanged -= h
            );
    }

    public static IObservable<T> GetObservableAddedValues<T>(
        this ObservableCollection<T> collection)
    {
        return collection.GetObservableChanges()
            .Where(evnt => evnt.EventArgs.Action == NotifyCollectionChangedAction.Add)
            .SelectMany(evnt => evnt.EventArgs.NewItems.Cast<T>());
    }
}

我添加了一个额外的帮助程序,只将新添加的项目公开为IObservable<T>,您可以这样使用:

ObservableCollection<int> collection = 
    new ObservableCollection<int>(new int[] { 1, 2, 3 });

collection.GetObservableAddedValues().Subscribe(
    i => Console.WriteLine("{0} was added", i)
);

框架中没有可观察的词典,尽管ObservableDictionary codeplex project似乎填补了这个空白,我确信它可以用类似的方式包装。

答案 1 :(得分:1)

使用ReactiveUI中的ReactiveCollection

var c = new ReactiveCollection<int>();
c.Changed.Subscribe(x => Console.Writeln(x.Value);
c.Add(1);

答案 2 :(得分:1)

对于那些无法选择使用IEvent来使用FromEventPattern界面的用户,可以改用:

public static class ObservableCollectionExtensions
{
    public static IObservable<EventPattern<NotifyCollectionChangedEventArgs>>
    GetObservableChanges<T>(this ObservableCollection<T> collection)
    {
        return Observable.FromEventPattern<
            NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
                h => collection.CollectionChanged += h,
                h => collection.CollectionChanged -= h
            );
    }

    public static IObservable<T> GetObservableAddedValues<T>(
        this ObservableCollection<T> collection)
    {
        return collection.GetObservableChanges()
            .Where(evnt => evnt.EventArgs.Action == NotifyCollectionChangedAction.Add)
            .SelectMany(evnt => evnt.EventArgs.NewItems.Cast<T>());
    }
}