Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RoutedUICommand within MVVM

I am struggling with MVVM in my application. I have there a TabControl whose every Tab hosts a control that allows somehow editing a file. For instance, text files or images. Each control is bound to a class from ViewModel area (as is depict at the diagram). I also have RoutedUICommands. One of these commands is WordWrap and only makes sense in case of text files. This command is used in MenuItem or a Button etc. I'd like to enable it only if a text control is the target for this command. How to do it properly according to MVVM?

More details:

diagram image

XAML for the Window has:

<Window.CommandBindings>
<CommandBinding Command="local:EditorCommands.WordWrap"
    Executed="WordWrapExecuted"
    CanExecute="CommandCanBeExecutedWhenAnythingIsOpen"/>
</Window.CommandBindings>

A menu item is used this way:

<MenuItem Command="local:EditorCommands.WordWrap"/>

The first thing is the Executed and CanExecute event handlers: they are in Window class although my understanding if MVVM is, that the logic should be in ViewModel only.

What's more, the sender in these function is an instance of a window. Why is it not a target of the command?

Should I write my own successors of RoutedUICommand for every command?

like image 803
Slávek Rydval Avatar asked Oct 18 '22 18:10

Slávek Rydval


1 Answers

A RoutedUICommand is not really suited to be used in a view model as it searches the visual tree from the focused element and up for an element that has a matching System.Windows.Input.CommandBinding object in its CommandBindings collection and then executes the Execute delegate for this particular CommandBinding.

Since the command logic should reside in the view model, you don’t want to setup a CommandBinding in the view in order to connect the command to a visual element.

Instead, you should create your own implementation of the ICommand interface or use one that is available in any of the MVVM frameworks out there. MvvmLight for example has a RelayCommand class: https://msdn.microsoft.com/en-us/magazine/dn237302.aspx.

How to use RelayCommand with the MVVM Light framework

And in Prism it is called DelegateCommand: https://www.codeproject.com/Articles/1055060/DelegateCommand-and-CompositeCommand-in-Prism

Please refer to the following blog post for more information about commands in MVVM: https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/

like image 59
mm8 Avatar answered Oct 21 '22 01:10

mm8