如何观察物品的集合是否有效?

时间:2012-06-27 06:55:27

标签: system.reactive reactiveui

我正在使用ReactiveUI和提供的ReactiveCollection<>类。

在ViewModel中我有一组对象,我希望创建一个observable来监视这些项目的IsValid属性。

这是我试图解决的问题。在我的ViewModel构造函数中。

this.Items = new ReactiveCollection<object>();

IObservable<bool> someObservable = // ... how do I watch Items so when 
                                   // any items IsValid property changes, 
                                   // this observable changes. There
                                   // is an IValidItem interface.

this.TheCommand = new ReactiveCommand(someObservable);

...

interface IValidItem { bool IsValid { get; } }

编辑保罗的回答让我大部分都在那里。解决方案如下。

this.Items = new ReactiveCollection<object>();
this.Items.ChangeTrackingEnabled = true;

var someObservable = this.Items.Changed
    .Select(_ => this.Items.All(i => i.IsValid));

2 个答案:

答案 0 :(得分:5)

这取决于你想要做什么与IsValid的结果。这是我如何做到的,虽然它并不完全直观:

// Create a derived collection which are all the IsValid properties. We don't
// really care which ones are valid, rather that they're *all* valid
var isValidList = allOfTheItems.CreateDerivedCollection(x => x.IsValid);

// Whenever the collection changes in any way, check the array to see if all of
// the items are valid. We could probably do this more efficiently but it gets
// Tricky™
IObservable<bool> areAllItemsValid = isValidList.Changed.Select(_ => isValidList.All());

theCommand = new ReactiveCommand(areAllItemsValid);

答案 1 :(得分:1)

由于您使用的是ReactiveUI,因此您有几个选择。如果您的对象是ReactiveValidatedObject s,您实际上可以使用ValidationObservable:

var someObservable = this.Items
    .Select(o => o.ValidationObservable
        .Select(chg => chg.GetValue()) //grab just the current bool from the change
        .StartsWith(o.IsValid)) //prime all observables with current value
    .CombineLatest(values => values.All());

如果它们不是ReactiveValidatedObjects,而是实现INotifyPropertyChanged,则只需替换第一行,并在ReactiveUI中为这些对象使用方便的ObservableForProperty扩展方法。您可以使用o.ValidationObservable代替o.ObservableForProperty(x => x.IsValid)。其余的应该是一样的。

这是一个非常常见的用例,我将其包装在IEnumerable<ReactiveValidatedObject>

的扩展方法中

我确信Paul Betts会有更优雅的东西,但这就是我所做的。