views:

1006

answers:

2

I am building a composite application using CAL/Prism. The main region is a tab control, with multiple types of views in it. Each view has a custom set commands that it can handle which are bound to toolbar buttons at the top of the window. I've done this before in non-CAL apps by simply setting the InputBinding on the command, but I haven't been able to find any such mechanism in the source code for the CAL modules.

My question is, what is the best way to hook up a keystroke to my view, so that when the user presses , the associated DelegateCommand object handles it? Hooking up a shortcut can't be THAT difficult...

Thanks,

John

+7  A: 

The MVVM Toolkit (http://wpf.codeplex.com/Wiki/View.aspx?title=WPF%20Model-View-ViewModel%20Toolkit) has a class called a "CommandReference" that will allow you to use a reference to a command as a keybinding.

<Window ...
    xmlns:toolkit="clr-namespace:CannotRememberNamspace;assembly=OrTheAssembly"
    >

    <Window.Resources>
        <toolkit:CommandReference 
                 x:Key="ExitCommandReference" 
                 Command="{Binding ExitCommand}" />
    </Window.Resources>

    <Window.InputBindings>
        <KeyBinding Key="X" 
                    Modifiers="Control" 
                    Command="{StaticResource ExitCommandReference}" />
    </Window.InputBindings>
</Window>

This'll do it.

Anderson Imes
Perfect! It took me more time to find the CommandReference class than it did to hook it in. I literally had the key bindings working in two minutes. Thanks a ton.
JMcDaniel
+9  A: 

Just for reference, the CommandReference class is currently not included in an assembly that you can reference, but is included with the M-V-VM project template. So if you don't build your application from the template, then you have to get the class from somewhere else. I chose to copy it from the sample project. I included it below to allow everyone easy access to this little chunk of goodness, but be sure to check for updates to the template in future versions of the M-V-VM Toolkit.

/// <summary>
/// This class facilitates associating a key binding in XAML markup to a command
/// defined in a View Model by exposing a Command dependency property.
/// The class derives from Freezable to work around a limitation in WPF when data-binding from XAML.
/// </summary>
public class CommandReference : Freezable, ICommand
{
    public CommandReference( )
    {
    }
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register( "Command", typeof( ICommand ), typeof( CommandReference ), new PropertyMetadata( new PropertyChangedCallback( OnCommandChanged ) ) );

    public ICommand Command
    {
        get { return (ICommand)GetValue( CommandProperty ); }
        set { SetValue( CommandProperty, value ); }
    }

    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        if (Command != null)
            return Command.CanExecute( parameter );
        return false;
    }

    public void Execute(object parameter)
    {
        Command.Execute( parameter );
    }

    public event EventHandler CanExecuteChanged;

    private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CommandReference commandReference = d as CommandReference;
        if (commandReference != null)
        {
            ICommand oldCommand = e.OldValue as ICommand;
            if (oldCommand != null)
                oldCommand.CanExecuteChanged -= commandReference.CanExecuteChanged;

            ICommand newCommand = e.NewValue as ICommand;
            if (newCommand != null)
                newCommand.CanExecuteChanged += commandReference.CanExecuteChanged;
        }
    }

    #endregion

    #region Freezable

    protected override Freezable CreateInstanceCore( )
    {
        return new CommandReference();
    }

    #endregion
}

Enjoy!

JMcDaniel
Hey thanks, that'll be nice for the next guy that comes along.
Anderson Imes
Thanks for posting the code! Seems like I was "the next guy" that came along, looking for that code... :)
gehho
I can't find Freezable in Silverlight, what am I missing?
kenny
@ Kenny - This code is WPF specific. But check out the Silverlight MVVM Toolkit project on Codeplex. (http://silverlightmvvm.codeplex.com/) They should have an implementation of the necessary command objects.
JMcDaniel