I don’t know if I should be excited by my newest discovery, or utterly annoyed.
You see, I wrote a while ago about the Model-View-ViewModel pattern, as blogged by Dan Crevier. He had encapsulated all actions that would be initiated in the View by the user into the ViewModel by creating what he called a CommandModel. The CommandModel used a RoutedCommand internally and you’d derive new CommandModels that would delegate command processing to the ViewModel. Then a CreateCommandBinding attached property would create the command bindings necessary to hook up the internal RoutedCommand. I disliked this implementation for two reasons. First, you had to derive a new CommandModel for every single command and this derived class had tight coupling to the specific ViewModel. This seemed like overkill. This problem was easy to correct by inverting the pattern and using a single CommandModel that you didn’t inherit from, but instead when you instantiated it you provided callbacks for the executed and can execute events. The second issue was a bit tougher, and I didn’t resolve it in the original post. The CreateCommandBinding was necessary to wire up the RoutedCommand, but it resulted in verbose and basically duplicated code in the XAML. For example, here’s how you’d code up a command in the XAML using Dan’s design.
<button loc:CreateCommandBinding="{Binding Path=AddCommand}" Command="{Binding Path=AddCommand.Command}"/>
Well, I didn’t like this, but fixing it was proving to be a bit of a pain. I eventually came up with a MarkupExtension that could be used like in the following.
<button Command="{loc:Command Path=AddCommand}"/>
I didn’t care for the code in this MarkupExtension, but it worked. I was all ready to share this with the world (in fact, I did share it with people at work), when a coworker sent me some links to other blog posts about this topic (thanks, Roger). There was a specific post by John Gossman that I took notice of. He had very similar code to Dan, but I noticed that in his XAML he wasn’t using a CreateCommandBinding or anything similar. So, how did it work? Well, looking closer at the code, I discovered that his CommandModel (he used a different name) didn’t use a RoutedCommand internally. Instead, it derived directly from ICommand! There was the key. If you don’t use a RoutedCommand, there’s no need to use command bindings to hook up event handlers. The ICommand interface is your gateway into the event handling. John still used a derived CommandModel for every command with tight coupling to the ViewModel, but it really doesn’t take much to invert this pattern in the same way we did previously (the code for my new ViewModelCommand is so simple that I’ll leave it as an exercise for the reader, unless someone begs me to provide it). Now the wiring in XAML just looks like the following.
<button Command="{Binding Path=AddCommand}"/>
Now this I like. A lot. But I feel stupid for having spent so much time creating my custom MarkupExtension here. I suppose there may some day be a need for a RoutedCommandModel, in which case that code will be dusted off. But honestly, given the use case for CommandModels, I’m not at all sure that will ever be the case. Only time will tell.
@"unless someone begs me to provide it"Oh, okay. I\’ll be the the one to beg.I kind of found what you were saying a little hard to follow. Sample code tends to clear things up.