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.

+3


source to share


1 answer


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));

      

+3


source







All Articles