我正在使用.net 4上的Rx框架中的第一步。
我正在尝试观察像List<int>
或Dictionary<x,x>
这样的集合。
当一个项目被添加到集合中时,它将在控制台中将其写为ToString()
。
任何想法?或一些代码示例 谢谢
答案 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>());
}
}