State handling in WPF-MVVM

mvvmstatewpf

I am looking for advice on handling states in a WPF MVVM environment.

As an example, assume we have

enter image description here

  • A TreeView (or some other ItemsControl) with some items and
  • a button that is enabled when an item is selected.

My ViewModel contains a property SelectedItem that is bound to the SelectedItem of the TreeView.

When the Button is clicked, we change to "special state": the current SelectedItem is stored somewhere for later reference (let's call the storing variable FirstSelectedItem). Then the Selection is cleared, the Button is disabled and the user is supposed to select an item again (can be any item, even the same one). So we get some entry in SelectedItem. Then the data of the item stored in FirstSelectedItem is changed depending on SelectedItem (change some internal properties that are not visible in the view). After this is done, SelectedItem is restored to contain FirstSelectedItem, the Button is enabled and the view is in "normal state" again.

I would like to know how you approach such problems in WPF. For me it is important to use the MVVM pattern and use codebehind only to redirect stuff to the ViewModel, and that it is possible to give every UI element a different look and behaviour depending on the current state. In a more complicated example, it might be that some controls become disabled or show up or execute another command than usual when a certain state is current.

For the looks, I think a way would be to have some property State in the ViewModel. The UI elements can then somehow make their looks dependent on that state (although I don't know how, but I'm sure it's possible).

For the behaviour, I have no idea. As far as I know, a Button can bind to one Command, and only one. Or can the binding be changed depending on State?

Best Answer

If I understand what you are saying, you need some UI cue to denote when the State property changes. There are many ways to do it in pure MVVM.

You could use a ValueConverter to convert the value of the state to a System.Windows.Visibility value have that bound to the visibility of certain elements in order to facilitate visibility changes based on the State property. You could do the same with a converter to convert state to a boolean in order to facilitate IsEnabled or IsReadOnly changes too.

Then, if you wanted the button command to change depending on the state you could change the binding and raise a PropertyChanged on the command for the button. Or just change the underlying method if you are using something like a RelayCommand seen here. Or you could just have a command that executes some routine that is affected by the State property. Or maybe pass in the state as a command parameter.

You could also use DataTemplates and bind a DataTemplate to the State property.

Facilitating a state change, depending on what that means, could be business logic, and that should probably not go in the ViewModel (Unless, like Rachel said, it is a very small app with limited need for abstraction). However, what you are attempting to do with the UI can be done with bindings and ViewModel property changes/notifications. There are 1,000 ways to skin a cat, you just need to find the one that best suits you.