Watch ItemChanged on two ReactiveLists
I have a ViewModel in which I would like to listen for changes to items in two ReactiveLists, Payments and AccountPayments. Lists are created and the ChangeTrackingEnabled parameter 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 the ObservableAsPropertyHelper readonly property:
readonly ObservableAsPropertyHelper<decimal> _totalPayments;
public decimal TotalPayments { get { return _totalPayments.Value; } }
I intend to set TotalPayments every time any of these items change in both lists. I've 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 one is compiling, 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 that won't compile. Is there a way to do what I am trying to do? Any help would be greatly appreciated.
source to share
The first will not work, since it observes changes in properties and ItemChanged
will not change itself, this is an observable.
The second option is quite correct, but requires some modification. WhenAnyObservable
requires all observables to be of the same type. Since you are not interested in the actual result, you can choose Unit
and combine the two:
this.WhenAnyObservable(a => a.Payments.ItemChanged).Select(_ => Unit.Default)
.Merge(this.WhenAnyObservable(a => a.AccountPayments.ItemChanged).Select(_ => Unit.Default));
You cannot select Unit.Default
internally WhenAnyObservable
as it re-writes this expression to watch for property changes to make sure it has the last observable. If neither Payments
, nor AccountPayments
will change (i.e. they are read-only), you can omit altogether WhenAnyObservable
:
Payments.ItemChanged.Select(_ => Unit.Default)
.Merge(AccountPayments.ItemChanged.Select(_ => Unit.Default));
source to share