ReactiveUI - why is simple ReactiveList.Changed -> ToProperty not working?
Asked Answered
H

2

5

I tried many different modifications but nothing helps. When I dig into sources it's a bunch of deep magic involving static state like ConditionalWeakTable etc.

private readonly ReactiveList<Item> _list = new ReactiveList<Item>();

private decimal _sum;
public decimal Sum
{
    get { return _sum; }
    set { this.RaiseAndSetIfChanged(ref _sum, value); }
}

_list
    .Changed
    .Select(_ => _list.Select(i => i.Value).Sum())
    .ToProperty(this, x => x.Sum)
Heptavalent answered 14/6, 2016 at 12:37 Comment(0)
M
8

The problem with your approach (in the question) is that you are not using the returned value from .ToProperty() call, which is ObservableAsPropertyHelper class. The returned value is simply ignored.

RxUI is actually simple when it comes to code around properties. They are simply a boilerplate which you should never modify significantly. In your case, you want to use an output property pattern, described here in the docs. Adapted to your example, you don't need a setter with RaiseAndSetIfChanged. Instead, you should use something like this:

private readonly ReactiveList<Item> _list = new ReactiveList<Item>();

private readonly ObservableAsPropertyHelper<decimal> _sum;
public decimal Sum {
    get { return _sum.Value; }
}

// in constructor
_sum = _list
    .Changed
    .Select(_ => _list.Select(i => i.Value).Sum())
    .ToProperty(this, x => x.Sum);

As you already noticed, ToProperty has an overload accepting an output reference to an ObservableAsPropertyHelper field in your ViewModel, which you can use (like in your answer). In the end, the overload you choose is a matter of style/taste. The below does exactly the same as above piece of code:

// in constructor, alternatively
_list
    .Changed
    .Select(_ => _list.Select(i => i.Value).Sum())
    .ToProperty(this, x => x.Sum, out _sum);
Milled answered 16/6, 2016 at 13:14 Comment(0)
H
1

Ok, I don't know why on earth there are other overloads, but this one works:

private ObservableAsPropertyHelper<decimal> _sum;

...
.ToProperty(this, x => x.Sum, out _sum));


public decimal Sum => _sum.Value;
Heptavalent answered 14/6, 2016 at 12:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.