Reputation: 65
I have a ViewModel in which I would like to listen for changes to items in two ReactiveLists, Payments and AccountPayments. The Lists are instantiated and the ChangeTrackingEnabled is set to true:
this.Payments = new ReactiveList<transaction.PaymentViewModel>();
this.Payments.ChangeTrackingEnabled = true;`
this.AccountPayments = new ReactiveList<AccountPaymentViewModel>();
this.AccountPayments.ChangeTrackingEnabled = true;`
Then, defined in my ViewModel, I have an ObservableAsPropertyHelper readonly property:
readonly ObservableAsPropertyHelper<decimal> _totalPayments;
public decimal TotalPayments { get { return _totalPayments.Value; } }
My intent is to set TotalPayments whenever any of these items change in both lists. I tried using WhenAny:
this.WhenAny(vm => vm.Payments.ItemChanged,
vm => vm.AccountPayments.ItemChanged,
(a, b) => a.Sender.Payments
.Where(x => x.Amount.HasValue).Sum(x => x.Amount.Value)
+ b.Sender.AccountPayments
.Where(x => x.Amount.HasValue).Sum(x => x.Amount.Value))
.ToProperty(this, vm => vm.TotalPayments, out _totalPayments);
While this compiles fine, it doesn't seem to catch the changes. I also tried using WhenAnyObservable:
this.WhenAnyObservable(
vm => vm.Payments.ItemChanged,
vm => vm.AccountPayments.ItemChanged)
.Select(_ =>
this.Payments.Where(x => x.Amount.HasValue)
.Sum(x => x.Amount.Value)
+ this.AccountPayments.Where(x => x.Amount.HasValue)
.Sum(x => x.Amount.Value))
.ToProperty(this, vm => vm.TotalPayments, out _totalPayments);
But this won't compile. Is there a way to accomplish what I am trying to do? Any help would be greatly appreciated.
Upvotes: 3
Views: 768
Reputation: 26213
The first won't work as it's observing property changes and ItemChanged
itself won't change, it's an observable.
The second is pretty much correct, but requires a bit of a modification. WhenAnyObservable
requires that all the observables are the same type. As you're uninterested in the actual result, you can select Unit
and merge the two:
this.WhenAnyObservable(a => a.Payments.ItemChanged).Select(_ => Unit.Default)
.Merge(this.WhenAnyObservable(a => a.AccountPayments.ItemChanged).Select(_ => Unit.Default));
You can't select Unit.Default
within WhenAnyObservable
as it re-writes this expression to observe the property changes to make sure it has the latest observable. If neither Payments
nor AccountPayments
will change (i.e. they're read only), you can omit the WhenAnyObservable
altogether:
Payments.ItemChanged.Select(_ => Unit.Default)
.Merge(AccountPayments.ItemChanged.Select(_ => Unit.Default));
Upvotes: 3