I have already read Josh Smiths article about binding commands to view model using RelayCommand. However I need to bind ApplicationCommands.Save to a view model so that when a user clicks the save menu item it is handled in the window. How is it possible?
5 Answers
There is a good tutorial to help bind application commands.
- Setup your command binding collection for your view to bind to in your view model. e.g.:
public CommandBindingCollection CommandBindings { get; } public YourViewModel() { //Create a command binding for the save command var saveBinding = new CommandBinding(ApplicationCommands.Save, SaveExecuted, SaveCanExecute); //Register the binding to the class CommandManager.RegisterClassCommandBinding(typeof(YourViewModel), saveBinding); //Adds the binding to the CommandBindingCollection CommandBindings.Add(saveBinding); }
Setup attached properties. Read the article on how to do that.
Then bind to it using attached properties.
<UserControl local:AttachedProperties.RegisterCommandBindings="{Binding CommandBindings}"> <Window.DataContext> <local:YourViewModel></local:YourViewModel> </Window.DataContext> </UserControl>

- 8,213
- 14
- 71
- 103
The best solution I'm aware of us to use a service. For example, an ICommandBindingsProvider like this:
public interface ICommandBindingsProvider
{
CommandBindingCollection CommandBindings { get; }
}
This gets injected into your ViewModel and used like this:
public MyViewModel(ICommandBindingsProvider commandBindings)
{
commandBindings.Add(new CommandBinding(....));
}
How the service gets injected will be dependent on what MVVM framework you're using. Most (but not all) support some sort of service injection capabilities. If you need a more concrete code example, look at Onyx which does service injection and has a service that does just this.

- 2,738
- 15
- 16
-
As I am not using any framework this is a bit problematic. I am just wondering if there is a way to do this without using a framework. For example ApplicationCommands.Save can be bind in the View. The view model can expose an ICommand which can be bound. Is there abolutely no way to connect these two(without breaking the pattern) – Jimmy May 18 '11 at 17:46
-
My answer applies even if you're not using a framework, you'll just have to figure out how to inject the service. I have a blog post about services in MVVM at http://digitaltapestry.net/blog/services-%E2%80%93-your-viewmodel-death-star that shows one simple way to do this without a framework of any kind. – wekempf May 18 '11 at 17:54
How is your save menu item being created? Somewhere it must be getting bound to the ApplicationCommands.Save? You can change that so that it binds to your ViewModel's save instead.

- 2,874
- 1
- 19
- 13
-
ApplicationCommands.Save is the command fired by the menu item. I just need to add a binding to the command in my view model. – Jimmy May 18 '11 at 17:34
-
1I assume you're suggesting he uses a command other than ApplicationCommands.Save? While a valid alternative some of the time, it's not always possible. A good example is Cut/Copy/Paste commands, where you'll want to use the built-in RoutedCommands used by the built-in controls. – wekempf May 18 '11 at 17:38
Or, you place the save command binding on the viewmodel, and then databind to it, something like (pseudo code)
in the viewmodel:
...
public Command SaveCommand { get { return yourCodeHere; } }
...
in the view:
<Button Command="{Binding Path=SaveCommand}" Content="Click"/>
Update: i just tried binding to a command in a commandbinding and it doesn't work. what i was thinking of was binding to a command.

- 24,225
- 5
- 58
- 76
-
I dont think this is possible in WPF. It would be really nice if the window can delegate a command to the view model like this. – Jimmy May 18 '11 at 17:50
-
ack! you're correct. Now i have to find the thing that made me think this was. i could have swore there was a way to bind either to command or something in there... – John Gardner May 18 '11 at 17:56
I have used this approach successfully in the past:
Start out by defining a CommandBindings property on ViewModels (same definition as on Views).
Then for each Command implemented by ViewModel, add a CommandBinding to ViewModel's CommandBindings.
Then, when you set:
view.DataSource = viewModel;
Also set:
view.CommandBindings.AddRange(viewModel.CommandBindings);
I think may be done using a binding of the CommandBindings property (can't remember for sure).

- 17,324
- 5
- 69
- 111