Saturday, May 16, 2009

MVVM CommandReference and KeyBinding

Recently when I was digging into MVVM sample in codeplex I came to notice one class named CommandReference.That class just contains a dependency property which is of ICommand.At first, I didn’t get why they created that class.But after seeing it’s application in the sample,I decided to add that in my MVVM.Core project because that was important when we come to a situation where  we need to bind a command to non dependency properties.Eg :InputBinding.Command
If you still didn’t get the importance of CommandReference just try to Bind a command to a KeyBinding as follows.

<Window.InputBindings>
<KeyBinding Modifiers="Control"
Key="N"
Command="{Binding CreateCustomerCommand}" />
</Window.InputBindings>


The result will be an Exception



A 'Binding' cannot be set on the 'Command' property of type 'KeyBinding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject



Reason is simple the Command property is not DependencyProperty.To get rid of this we have to use the CommandReference.The usage is as follows.



<Window.Resources>
<coreView:CommandReference x:Key="newCust"
Command="{Binding NewCustomerCommand}" />
</Window.Resources>
<Window.InputBindings>
<KeyBinding Modifiers="Control"
Key="N"
Command="{StaticResource newCust}" />
</Window.InputBindings>

See the sample for more details.This is again a modified version of Josh Smith's MVVM sample.

15 comments:

  1. We use the CommandReference for exactly for this purpose. But now we have a problem with the CanExecute of the original Command. It's not evaluated anymore.
    Supose we have a command "MyCommand". When we set this as the Command of a Button, the CanExecute is evaluated as expected. But the moment we wrap MyCommand in a CommandReference, and bind the button-command to this commandreference, CanExecute is only evaluated one time (at startup), not when we actually need it.

    ReplyDelete
  2. Somehow I totally missed this part of the MVVM sample. Thanks for bringing it to my attention. This was just what I needed and it was already there. Great!!

    kpierce8@gmail.com

    ReplyDelete
  3. Thank you so much, I was wondering exactly how to do that in MVVM. Works like a charm once we had the CommandReference class that is available in the samples.

    ReplyDelete
  4. How can you use this with a command parameter binding?

    ReplyDelete
  5. Let me know your feedback when you used this with a CommandParameter

    ReplyDelete
  6. For anyone coming to this page from a web search, since WPF 4.0 the Command and CommandProperty properties of an InputBinding (like KeyBinding) are now backed by DependencyProperties, so you *can* directly bind to them, without needing a CommandReference.

    ReplyDelete
  7. Thanks Jordan for making my blog up to date :-)

    ReplyDelete
  8. Joy, I was very happy to find your blog post! I applied it in my WPF project which is limited to .NET 3.5 for now. Before finding your post, I was trying to bind the KeyBinding directly to an ICommand (or a RelayCommand from Josh Smith's examples) and got an error that a binding can only be set on a DependencyProperty of a DependencyObject.

    ReplyDelete
  9. it works great, but am using it in the usercontrol inside the tab item. so it only fires when i click some where inside in the usercontrol, its not working when loading the form. it works only when the form is focused or clicked. is any solution for this?

    ReplyDelete
  10. Nice blog entry! I have written a series of posts on this topic. Check them out here: http://coderscouch.com/tags/input%20bindings

    ReplyDelete
  11. simple and sober. Very Good!!!

    ReplyDelete
  12. What is coreView namespace? Where is it set? Why is it not part of the article?

    ReplyDelete