Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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)
like image 781
Den Avatar asked Jun 14 '16 12:06

Den


2 Answers

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);
like image 159
pmbanka Avatar answered Nov 15 '22 04:11

pmbanka


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;
like image 27
Den Avatar answered Nov 15 '22 04:11

Den