phreezie
phreezie

Reputation: 324

ReactiveUI: R/W properties vs. Output Properties

I have a "Close" button and an Expander linked in my MVVM view like so:

this.BindCommand(ViewModel, vm => vm.CloseResults, v => v.CloseButton);
this.OneWayBind(ViewModel, vm => vm.HasExecuted, v => v.Panel.IsExpanded);

If the user clicks on the button, the expander should be collapsed. In the view model, I have a ReactiveCommand that should take care of this:

public ReactiveCommand<object> CloseResults { get; protected set; } =
   ReactiveCommand.Create();

In the view model, HasExecuted is an Output Property that is supposed to expand/collapse the expander depending on its value:

private readonly ObservableAsPropertyHelper<bool> _hasExecuted;
public bool HasExecuted => _hasExecuted.Value;

So to hook up the command with the button, I'm binding HasExecuted to the command like so:

CloseResults.Select(_ => false).ToProperty(this, vm => vm.HasExecuted, out _hasExecuted);

This doesn't seem to do anything. However, if I use a read-write property instead and hook it up like this:

CloseResults.Subscribe(_ => { HasExecuted = false; });

it works perfectly. Can anyone explain why the Output Property doesn't work in this case? Isn't the ToProperty extension supposed to subscribe to the IOberservable<bool> that Select(_ => false) is returning?

I'm still in the middle of getting the hang of all this, so there's probably something obvious I'm missing.

Upvotes: 1

Views: 560

Answers (1)

RandomEngy
RandomEngy

Reputation: 15413

Output properties are meant to reflect the state of other properties or observables. It's basically a little formula you write that gives a property as an output. You aren't meant to set them directly. See the docs for this.

CloseResults.Select(_ => false).ToProperty(this, vm => vm.HasExecuted, out _hasExecuted);

^ This is saying "No matter what CloseResults it giving as an output, return an Observable that always returns false"

CloseResults.Select(_ => false).ToProperty(this, vm => vm.HasExecuted, out _hasExecuted);

^ This is saying "Take that always-false Observable and turn it into the HasExecuted output property."

Your read/write property is more suited to what you're trying to do here.

Upvotes: 1

Related Questions