如何动态地将可观察对象的反应列表合并到ReactiveUI中的一个observable中,C#

时间:2017-03-06 07:11:40

标签: c# reactiveui

我试图使用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。它的商品属于ReactiveObjectA,其中包含另一个ReactiveList bListbList项属于ReactiveObjectB的属性。 从aList开始,我如何应对aListbList及其所有属性中的任何变化?

我正在尝试这样的事情:

Observable.Merge(viewModel.aList.Select(x => Observable.Merge(x.bList.Select(y => y.Changed))))

但是,这只会在执行此代码时观察已存在的B中的更改。是否可以自动观察aListbList中的更改并订阅新项目?

或者也许可以Observable.Merge观看ReactiveList并自动订阅任何新项目并取消订阅已删除的项目?

我知道,我可以手动完成,但这可能不会像预期的那样使用ReactiveUI。有什么想法吗?

2 个答案:

答案 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

的更多详情