phil
phil

Reputation: 638

Correct way to use ObservableAsPropertyHelper and this.WhenAny on a ViewModel

Say I have a menu for a sketching pad. It has a toolbar with 3 toggle buttons: Pencil, Pen, Eraser. Only one of the 3 tools can be selected at any time and no tools selected is also a legit option.

My VM backing needs to keep track of the selected state. Being an observable is a big plus as other VMs will need to know the state too. I think I would like to use an enum. Something to the effect of

enum SelectedTool
{
  None=0,
  Pencil,
  Pen,
  Eraser
}

I am trying to figure out the best way to set up this VM using a ReactiveObject. I think that the SelectedTool state variable should be readonly and set upon the tool selection (should this be ObservableAsPropertyHelper?). I would also like the initial state of the enum to be None. I also am not sure if each button should have a bool ReactiveProperty or not for backing. If those bool backings exist, then I am going to have to keep the state consistent in the VM, which could be a pain as more tools are added. I am wondering if there is a way for me to use a WhenAny on the bools to set the appropriate state.

Thanks

Upvotes: 1

Views: 384

Answers (1)

Ana Betts
Ana Betts

Reputation: 74654

I think that the SelectedTool state variable should be readonly and set upon the tool selection (should this be ObservableAsPropertyHelper?)

I would actually drive this the other way around - the SelectedTool as an Enum should be the Source Of Truth™, and have the button state be a reflection of that.

var pencilToggled = this.WhenAnyValue(x => x.SelectedTool == SelectedTool.Pencil);

// We can only toggle Pencil when it's not currently toggled
var togglePencil = ReactiveCommand.Create(pencilToggled.Select(x => x != true));
togglePencil.Subscribe(_ => this.SelectedTool = 
    (this.SelectedTool == SelectedTool.Pencil ? SelectedTool.None : SelectedTool.Pencil));

You could get super clever and use the four commands + Merge + ToProperty to make this fully Functional, but you wouldn't get much benefit out of it imho.

Upvotes: 2

Related Questions