Using WPF Built-in Commands with ViewModel

Ok, so I'm trying to understand the concept of WPF commands. They seem pretty simple until you try to forward a command to something that doesn't match the XAML code. I have seen several ways to do this with custom commands, but have no direct explanation of how to do this with WPF built-in commands. Things like Open, Save, Cut, etc.

Is there an easy way, using the RelayCommand class or something else, to pass the Open command to my ViewModel?

+4
source share
4 answers

The built-in WPF ApplicationCommands and the like were not originally designed with MVVM in mind, so they really don't match when you try to put them in the ViewModel.

In WPF 4, you can now bind InputCommands to your ViewModel:

https://www.thomaslevesque.com/2009/10/26/vs2010-binding-support-in-inputbindings/

An alternative is to use DelegateCommands , which you can implement yourself or get from a library, such as Prism . You can define DelegateCommand as an object in your view model and bind it to your view.

Once you work with the binding, you determine what the command does in your viewmodel code.

+6
source

If you are working with MVVM with WPF, I highly recommend looking at a structure that will help you, for example:

+2
source

One way is to use a nested property to allow the ViewModel to define CommandBindings in the view. Check out my blog post:

CommandBindings with MVVM

+1
source

Suppose your ViewModel provides the New command. You can reassign Application.New binding to VM with such code. In XAML:

 <Window.CommandBindings> <CommandBinding Command="New" /> ... </Window.CommandBindings> 

Then in the code you can do something like this. (I like to leave the code outside the code, so I put it in the utility class.)

 foreach (CommandBinding cb in CommandBindings) { switch (((RoutedUICommand)cb.Command).Name) { case "New": cb.Executed += (sender, e) => ViewModel.New.Execute(e); cb.CanExecute += (sender, e) => e.CanExecute = ViewModel.New.CanExecute(e); break; } } 

Anonymous methods provide an exchange between RoutedUICommand and ICommand.

EDIT:. As an alternative, it was considered that it is best to set the binding of commands explicitly using the CommandManager rather than adding handlers.

 CommandManager.RegisterClassCommandBinding(typeof(MainWindow), new CommandBinding(ApplicationCommands.New, (sender, e) => ViewModel.NewScore.Execute(e), (sender, e) => e.CanExecute = ViewModel.NewScore.CanExecute(e))); 
0
source

Source: https://habr.com/ru/post/1337394/


All Articles