3

In the past with windows forms I both used parts of Composite UI Application Block combined with some centralised command handling and security rules to achieve a loosly coupled MVC approach to interface to command execution binding. I would like to know how to do this in WPF with the ICommand or RoutedCommand?

My prior implementations would consist of the following:

  1. Associate every command with a string in the form of a REST based URI, such as cmd://myapp/orders/create
  2. Write a custom ICommand (not to be confused with WPF) which would handle the command execution, it just had an Execute() method, and CanExecute property along with Undo() and `CanUndo if it supported undo capabilities.
  3. Interface objects required to execute the command would then be bound loosely by
    1. Handling the Click event which would not know about which command to execute, but merely pass the centralised CommandManager a command name to be executed.
    2. Once the CommandManager recieves a command execution it would simply use the many-to-many capabilities in Composite UI Application Block to raise the command event.
    3. Before the actual command execution the command manager performs a security check which is basically assking my SecurityManager if the logged in user can perform a command string, security rules are loaded through an XML file and consist of patterns, such as 'cmd://myapp/finance/*'
    4. Once the command event is raised on the recieving command it would then be responsible for determining state and context through view-model based dependencies.

I like this approach because it's easy to write, loosly coupled, and commands are only allowed to obtain interface state through view-model's which are found via DI. Composite UI Application Block also made it easy for me to "enable/disable/unavailable"

I can similarly replicate almost everything exccept the 'string' representation of a command, this is vital as the security context we have written can lock down a whole section by handling command patterns such as cmd://myapp/finance/*, we can also then let the user decide their command shortcut bindings etc.

Key requirements for me are:

  1. Commands need to be represented as strings, this is an absolute requirement.
  2. Must be able to state a command string is "enabled", "disabled", and "Unavailable" (meaning it should be hidden in the UI.
  3. Interface elements must not know how to handle a command, or how to provide context, this is the commands responsibility itself via view-model objects it discovers.
  4. Command execution must be centralised, i.e. I need a command manager object that handles raising the event to perform the command execution along with maintianing an undo stack.

EDIT: I've just thought about how to provide the command binding by using MEF exports to expose custom metadata providing the command name, an ImportMany can then load these up in my CommandManager, now it's just a matter of

  1. Telling interface items a Command String that they invoke, and;
  2. Allowing command strings to have state changed (enabled/disabled/unavailable).

EDIT 2: I have thought about a solution where my CommandManager accepts a Register(Control, String) bethod where one can register a control with a command string, the command manager can then handle the enabling/disabling/hiding of UI elements as their state changes and bind events to them, this provides much greater flexibility and decoupling as while also alowing for user customizing (moving menus, button configurations, keyboard shortcuts etc..). This raises a concern though that I'm not using a single point of the ICommand facility provided by WPF, in the end I don't think it matters, but I would like to know if the commanding facility provided with WPF could be used in such a simple way as I have defined. The other advantage is this method is not WPF specific and can be used anywhere.

Brett Ryan
  • 26,937
  • 30
  • 128
  • 163

1 Answers1

0

it seems to me you are bending yourself to fit a pattern you once used in winforms to be used in wpf also. that usually is not the best approach.

but specific for your problem I just wanted to say: if you are skipping ICommand entirely you definately loose stuff wpf does behind the scenes. For example: ICommands CanExecute method. The WPFs commandmanager requeries that method depending on user input to your application. You'd otherwise have to handle propagation of "enabled"/"disabled"/"unavailable"-State changes yourself and implement your own logic to enable/disable the button.

also commands can be used for more than just Click events.

and last: commands can be executed without WPF - it's just an interface and not explicitly bound to wpf

Markus Hütter
  • 7,796
  • 1
  • 36
  • 63
  • Thanks Markus. I think what's happening is I'm bending myself to find a way to make `ICommand` flexible, it appears to be too tightly coupled with the implementation of a command. The most important concept is for commands to have names or keys represented as strings to allow a security model to determine if a command can be executed from a security context. It seems to me that the model exposed by WPF is more tuned towards actions acting on interface elements, rather than actions acting on domains. – Brett Ryan Apr 10 '11 at 12:53