Question

I thought I'd post here in the hope that maybe someone with MVVM expertise would be able to offer opinions on whether the following is a good idea:

I'm using Sacha Barber's Cinch MVVM framework, which includes Marlon Grech's SimpleCommand class.

One thing this class doesn't have which some other alternatives have is a Text property, which can be commonly used to bind UI elements to the 'Title' of the command operation. Consequently I've been writing an extension to this class which exposes a Text property.

Now, what I've run into is a use case where I'm using a command to toggle connectivity to a device. There's a bunch of different ways I could implement this (aren't there always - it's software!). One way would be to expose multiple command objects from my ViewModel - one for 'Disconnect' and one for 'Connect; have the view model expose a property which indicates the connection state (IsConnected) and have the view conditionally bind to either the Connect command or Disconnect command. My reaction to this option though, is ... yuck!

What I initially started looking at instead was not only providing a Text property but also having the command object implement INotifyPropertyChanged so that the text property can be dynamically altered by the viewmodel to 'Connect' or 'Disconnect' according to system state. Doing this, I can avoid having multiple commands and just expose a single 'ToggleConnection' command object.

Starting down this path though, it occurs to me that there may be other variations of this pattern whereby the UI needs to be altered according to command state. For example, in addition to changing the command's text according to connection state, you may have places where an icon needs to change according to connection state. So, I started writing a 'Stateful' class which implements INotifyPropertyChanged, and exposes two properties - 'Text' and 'State'. I've made the class generic so that the type of State can be defined by the user (I usually prefer not to use 'object' where avoidable).

The question I have is... Do you think this is a good or bad idea? It may be diverging from the original intention / design of commands; From what I've seen it may in general be the case that command objects were intended to be stateless as they are the 'verbs' of the system. With routed commands, if I understand things correctly only the target of the command would usually be expected to have state. Particularly since the same command could be routed to different handlers depending on where command bindings are declared.

So, I'm thinking that at least with routed commands, state would not make sense.

However, I'm not dealing with routed commands - I'm specifically dealing with MVVM commands. In this case there basically is no conditional routing of commands - the MVVM views bind directly to a particular viewmodel's command objects and it's execute and canexecute handlers.

In this case, does it make sense?

I've attached a copy of the code in question, in case it's of use/interest.

Thanks, Phil

Was it helpful?

Solution

It's really up to you what you think would be easier to work with.

I personally do not put the .Text property on my commands simply because I get no reuse out of these commands. It's different with the RoutedUICommands provided in the framework (or similar custom static commands) because they are reused everywhere and if the translation of "Exit" were to change on that command, it would be reflected throughout the application. This is not the case in your example - everything would be one-off.

In your case this text of your button text is really decoupled from your command (even though one affects the other) and so it's probably going to end up being easier and a little less code to decouple them, but the difference isn't going to be that much and it will end up being a matter of taste more than anything.

I'm definitely with you on the 2 commands thing - blech. Most button delegates you write will have to react to state in some way (service you talk to is down, this data needs to be populated this way if the user selected this, etc), so I don't really think it's wrong to have the delegate adapt to stateful information on the ViewModel.

Anyway, this is a bit wordy... the take-away is "do whatever feels comfortable".

OTHER TIPS

Like the last poster said, "Whatever feels comfortable."

In my case, I usually use something like the DelegateCommand. If I need to bind to some data, I bind to the VM. When the command is executed, its executed within my VM (via the delegate provided to the DelegateCommand at init). Then the executed delegate may/maynot run some reusable code to satisfy the command.

It sounds like you want to use the Command as it's own VM. I never thought of doing this before myself, but if it feels good to you, do it! :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top