0
votes

Situation :

I've started coding a model and its commands inside a WPF project, now I've decided to move this 'model' to a class library so it does not depend on any of the WPF types.

The ultimate goal is to be able to use it on another framework than WPF, Forms for instance.

For the model it was painless, there were no dependencies at all on any WPF type, however the model commands class returns a bunch of errors : Cannot resolve symbol 'RoutedUICommand'

Here's an extract of the class :

public static class MyModelCommands
{
    private static readonly RoutedUICommand _addFiles;

    static MyModelCommands()
    {
        _addFiles = new RoutedUICommand("Add files", "AddFiles", typeof (MyModelCommands));
    }

    public static RoutedUICommand AddFiles
    {
        get { return _addFiles; }
    }

    // ...
}

Looking at the RoutedUICommand documentation :

The Execute and CanExecute methods on a RoutedCommand do not contain the command logic for the command, as is the case with a typical ICommand. The Execute and CanExecute methods on a RoutedCommand do not contain the command logic for the command, as is the case with a typical ICommand.

I've come to the conclusion that I should use my own derivation of ICommand, I'd even benefit from that in the sense that I'll implement the commands logic inside the class library, which is great.

But what about the WPF project, should I create a facade of this class that encompasses these commands in RoutedUICommand(s) and update my CommandBindings to the handlers in the class library ?

2

2 Answers

1
votes

The RoutedUICommand class is a UI class that is used in views and their code behind or view models. Your model classes shouldn't have any ICommand fields or properties in them. How your models are displayed or edited in the UI is not the concern of your model classes. This is to keep the separation between your UI layer and your business model layer.

When you follow this pattern, then you can provide different UIs for the same model classes. For example, if you were to add a WinForms UI for your models, you can simply use its event system to provide the functionality, so the ICommands are not necessary. Rather than trying to re-invent the wheel with your own custom command logic, just use whatever means are available on whatever Framework you use.

1
votes

The special thing about RoutedCommand is it's built in use of Command Manager ,

For instance :

1) CommandManager.RequerySuggested to raise ICommand.CanExecuteChanged.

2) CommandManager.RegisterClassCommandBindings in order to associate a command with a Execute and CanExecute delegates of instances of specific types.

These built in solutions come with a small performance cost , as discussed here
A discussion about the fact that CommandManager's RequerySuggested is raised allot

(every time the UIElement or any of it's ancestor's gets any UI Notification.)

Implementing your own ICommand and still interacting with the UI would require you to raise CanExecuteChanged event by hand in order to notify ICommandSource objects like Button to raise their command's can execute delegate.

Secondly in order to attach commands in a decoupled manner you would have to implement some sort of CompositeCommand object which is a kind of Event aggregator for Commands.

So as you can see it is possible but the all ICommand objects are meant to correspond to the UI and the WPF framework so there's no real point in placing them in a different class library that you would like to use with other frame works.