by StefanOlson via Stefan Olson's Blog on 11/2/2008 12:11:57 PM
Whilst building the WPF version of our virtual tour software we came across a situation where routed commands, the built in command infrastructure in WPF would not actually achieve what we wanted. The way routed commands work is that they work their way up the visual tree trying to find a CommandBinding from someone who was interested in processing that command. Unfortunately in a number of situations in the viewer that is not the behaviour that we want. Sometimes you could be in a different part of visual tree but still want a command to execute when you press a keystroke for example.
Confused yet? Let's get on to a concrete example. Below is a screen shot of the virtual tour viewer running in WPF:
If the keyboard focus happened to be in the index for example you would still want the navigation buttons beside the word Introduction to be operational via the keyboard shortcut (Ctrl+Right):
Of course with a routed command it would simply try and find a binding from the current keyboard focus (index) up to the main window. As the command is handled by the TourContentControl on the right it would never know about the request.
Therefore we have come up with a new concept borrowed, in a way, from Expression Blend, called Targeted Commands. The way Targeted Commands work is that each window registers the commands they want to receive with the TargetedCommandManager. So when a command is executed the TargetedCommandManager goes through the list of registered bindings and finds out which window is interested in the current command. It can then use that given command binding to execute the command.
So, what do we want to achieve with this:
So let's look at some code. First off, how do we create a command?
public MainWindow() { InitializeComponent(); _commandManager = new TargetedCommandManager(this, null);
public ViewerTitleControl() { InitializeComponent(); _bindings.Add(new TargetedCommandBinding(MainWindow.NextObjectCommand,NextObjectExecuted)); _bindings.Add(new TargetedCommandBinding(MainWindow.PrevObjectCommand,PrevObjectExecuted)); _bindings.Add(new TargetedCommandBinding(MainWindow.ParentObjectCommand,ParentObjectExecuted));
Of course there is support for CanExecute, which ties into the existing CommandManager system of WPF, or in Silverlight with the CommandManager that is part of our Silverlight WPF compatibility library, which contains the Targeted Command System.
So the final part is to ensure that our bindings are registered with the TargetedCommandManager when the window is displayed. So we will create functions to add and remove the bindings:
internal void AddCommands() { TargetedCommandManager.Current.AddCommandBindings(_bindings); } internal void RemoveCommands() { TargetedCommandManager.Current.RemoveCommandBindings(_bindings); }
So in this case when the TourContentControl (which is the larger window containing the title control) is displayed we call TitleControl.AddCommands(). We call TitleControl.RemoveCommands() when a different type of window appears in the content area of the MainWindow.
So now, in both WPF and Silverlight you automatically get the correct handling of the keyboard so that the command is routed to the correct place that actually wants to do something with it! Unfortunately, in Silverlight you don't actually get any ALT key commands (e.g: ALT+S) coming through to the keyboard handler as they are eaten by the browser (I’ll blog about that soon).
You assign the command to a button in exactly the same way as you always have, using the Command attribute. If you want the tooltip to automatically be created with a description pulled from the application resources using the name of the command, you can do it via the provided attached property (CommandHelpers.Command) which we have also created for Silverlight.
Here's an example of automatic tooltip creation, running under Silverlight:
So there we have one possible solution for handling commands in an application. Because of the design the TargetedCommandBinding could equally be put in the ViewModel rather than the View as we have done here.
The source code for the Targeted Command system and our routed command implementation for Silverlight and other associated classes will be available in the near future as part of the open source Silverlight WPF compatibility library we are creating. Keep watching for more news!
…Stefan
Original Post: Targeted commands in WPF and Silverlight
The content of the postings is owned by the respective author. Silverlight Feeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on Silverlight Feeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.