Dan*_*nks 7 .net c# system.reactive
我有一个Class,MyClass它实现INotifyPropertyChanged并具有一些实现的属性PropertyChanged.当MyClass.MyProperty变化,PropertyChanged如预期火灾.另一个类包含一个.SortedList<MyClass>我已经尝试将事件合并到包含该类的类中的单个observable中SortedSet<MyClass>和订阅它,但它似乎没有任何事件.这是我正在尝试的:
Observable.Merge(MySortedList.ToObservable())
.Subscribe(evt => Console.WriteLine("{0} changed", evt.MyProperty));
Run Code Online (Sandbox Code Playgroud)
我想要得到的是一个单一的observable,它包含了我所有项目中的所有事件SortedList<MyClass>.我已经尝试过使用ObservableCollection,但是这并没有改变任何东西,也没有预料到真的,因为当包含项的属性发生变化时,它不会触发collectionchanged.我可以听取单个元素SortedList<MyClass>并查看PropertyChanged事件触发器,但我想要的是一个包含来自所有元素的所有PropertyChanged事件的流的单个Observable SortedList<MyClass>.
看起来这应该是使用Rx相当容易的事情,但我似乎无法弄清楚如何.
我在这个主题上为RxCookBook制作了一篇文章,你可以在这里找到 https://github.com/LeeCampbell/RxCookbook/blob/master/Model/CollectionChange.md 关于PropertyChange通知的更多文章在这里https:// github. COM/LeeCampbell/RxCookbook /斑点/主/型号/ PropertyChange.md
它通过聚合来自的变化来解决您的需求ObservableCollection<T>.通过使用,ObservableCollection<T>您还可以在从集合中添加或删除项目时收到通知.
如果您不想使用ObservableCollection<T>(即您只想跟踪集合的给定快照的属性),那么您将需要执行其他操作.首先,我假设你有一个INoftifyPropertyChanged对IObservable<T>扩展方法,或者你只是要使用标准的事件IObservable<T>的方法.
接下来,您可以投射的值列表为变化序列的列表即IEnumerable<T>到IEumerable<IObserable<T>>.这允许您使用Observable.Merge以将更改列表展平为单个更改流.
如果您不想使用上面的链接,请参阅以下示例:
void Main()
{
var myList = new List<MyThing>{
new MyThing{Name="Lee", Age=31},
new MyThing{Name="Dave", Age=37},
new MyThing{Name="Erik", Age=44},
new MyThing{Name="Bart", Age=24},
new MyThing{Name="James", Age=32},
};
var subscription = Observable.Merge(myList.Select(t=>t.OnAnyPropertyChanges()))
.Subscribe(x=>Console.WriteLine("{0} is {1}", x.Name, x.Age));
myList[0].Age = 33;
myList[3].Name = "Bob";
subscription.Dispose();
}
// Define other methods and classes here
public class MyThing : INotifyPropertyChanged
{
private string _name;
private int _age;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
public int Age
{
get { return _age; }
set
{
_age = value;
OnPropertyChanged("Age");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public static class NotificationExtensions
{
/// <summary>
/// Returns an observable sequence of the source any time the <c>PropertyChanged</c> event is raised.
/// </summary>
/// <typeparam name="T">The type of the source object. Type must implement <seealso cref="INotifyPropertyChanged"/>.</typeparam>
/// <param name="source">The object to observe property changes on.</param>
/// <returns>Returns an observable sequence of the value of the source when ever the <c>PropertyChanged</c> event is raised.</returns>
public static IObservable<T> OnAnyPropertyChanges<T>(this T source)
where T : INotifyPropertyChanged
{
return Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
handler => handler.Invoke,
h => source.PropertyChanged += h,
h => source.PropertyChanged -= h)
.Select(_=>source);
}
}
Run Code Online (Sandbox Code Playgroud)
哪个会输出:
Lee is 33
Bob is 24
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5706 次 |
| 最近记录: |