我试图使用ReactiveUI来制定一些可观察的内容。虽然有些事情已经很好用,但我仍然无法找到适合其他事情的ReactiveUI方法。我还是ReactiveUI的新手。
public class ViewModel : ReactiveObject {
public ReactiveList<A> aList {get;}
}
public class A : ReactiveObject {
public ReactiveList<B> bList {get;}
}
public class B : ReactiveObject {
//some properties
}
我有ReactiveList
aList
。它的商品属于ReactiveObject
类A
,其中包含另一个ReactiveList
bList
。 bList
项属于ReactiveObject
类B
的属性。
从aList
开始,我如何应对aList
,bList
及其所有属性中的任何变化?
我正在尝试这样的事情:
Observable.Merge(viewModel.aList.Select(x => Observable.Merge(x.bList.Select(y => y.Changed))))
但是,这只会在执行此代码时观察已存在的B
中的更改。是否可以自动观察aList
和bList
中的更改并订阅新项目?
或者也许可以Observable.Merge
观看ReactiveList
并自动订阅任何新项目并取消订阅已删除的项目?
我知道,我可以手动完成,但这可能不会像预期的那样使用ReactiveUI。有什么想法吗?
答案 0 :(得分:3)
Changed
上的ReactiveList
属性会在列表更改时通知您。使用此选项可以了解何时更新已包含ReactiveList
s。
要获得每次ReactiveList<A>
和ReactiveList<B>
更改时都会记录的可观察量,您可以执行以下操作:
aList.Changed
.Select(change => Observable.Merge(viewModel.aList.Select(x => Observable.Merge(x.bList.Select(y => y.Changed)))) // Create observable to notify when the sub collections change
.StartWith(change) // Send the notification that aList has changed immediately
)
.Switch() // Only subscribe to the latest change notifications from the sub collections in the most recent aList
.Subscribe(changes => { /* Do something */});
答案 1 :(得分:0)
您可以尝试我们的库ReactiveCompositeCollections,而不是使用ReactiveList,它允许您使用LINQ展平可观察的集合。
public class ViewModel : ReactiveObject {
public ICompositeSourceList<A> aList {get;}
}
public class A : ReactiveObject {
public ICompositeSourceList<B> bList {get;}
}
public class B : ReactiveObject {
//some properties
}
然后
ViewModel vm = ... ;
IComposteList<B> all =
from aItem in vm.aList
from bItem in aItem.bList
select bItem;
// Subscribe to the stream of flattened items
all.Items.Subscribe((ImmutableList<B> bItems)=>DoSometing(bItems));
// or create an INPC object with a property Items
using(var s = allLines.Subscribe()){
RenderLines(s.Items);
}
好消息是,这不是LINQ over IEnumerable它是LINQ over ICompositeCollection,其中ICompositeCollection是一个反应集合。源列表中的任何更改都会被反映到结果列表中。
内部结构都使用不可变列表,因此性能可能是大型集合的问题。
可以将ICompositeCollection转换为WPF可用的ObservableCollection
ObservableCollection<B> observableBs =
all.CreateObservableCollection(EqualityComparer<B>.Default)
https://github.com/Weingartner/ReactiveCompositeCollections#using-icompositecollection-with-wpf
的更多详情