Как связать нажатие клавиши с DelegateCommand в Composite WPF?

Я создаю составное приложение с использованием CAL / Prism. Основная область - это вкладка с несколькими типами представлений в ней. Каждое представление имеет настраиваемый набор команд, которые он может обрабатывать, которые привязаны к кнопкам панели инструментов в верхней части окна. Я делал это раньше в приложениях, отличных от CAL, просто устанавливая InputBinding в команде, но мне не удалось найти какой-либо такой механизм в исходном коде для модулей CAL.

Мой вопрос: как лучше всего связать нажатие клавиши с моим представлением, чтобы, когда пользователь нажимает Alt + T, связанный объект DelegateCommand обрабатывал его? Найти ярлык не так сложно ...


person JMcDaniel    schedule 23.09.2009    source источник
comment
J, я не могу найти Freezable в Silverlight, что мне не хватает?   -  person kenny    schedule 16.09.2010


Ответы (3)


В MVVM Toolkit есть класс называется CommandReference, который позволит вам использовать ссылку на команду в качестве привязки клавиш.

<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>

Это сделаю это.

Изменить: с тех пор, как это было написано, WPF 4.0 устранил эту конкретную проблему, и вам больше не нужно использовать обходной путь статических ресурсов. Вы можете ссылаться на команду в своей модели просмотра непосредственно из KeyBinding.

person Anderson Imes    schedule 23.09.2009
comment
Идеально! На то, чтобы найти класс CommandReference, у меня ушло больше времени, чем на то, чтобы подключить его. У меня буквально за две минуты сработали привязки клавиш. Благодаря тонну. - person JMcDaniel; 24.09.2009
comment
Я думаю, что оба ответа следует объединить, полный ответ на самом деле оба (это и JMcDaniel). Одно неполно без другого. Мне нужно было и то, и другое, чтобы решить проблему. Спасибо! - person bluediapente; 02.06.2011

Для справки: класс CommandReference в настоящее время не включен в сборку, на которую вы можете ссылаться, но включен в шаблон проекта M-V-VM. Поэтому, если вы не собираете свое приложение из шаблона, вам придется получить класс откуда-то еще. Я решил скопировать его из образца проекта. Я включил его ниже, чтобы каждый мог легко получить доступ к этому маленькому кусочку добра, но обязательно проверяйте наличие обновлений для шаблона в будущих версиях 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
}

Наслаждаться!

person JMcDaniel    schedule 24.09.2009
comment
Эй, спасибо, это будет хорошо для следующего парня, который появится. - person Anderson Imes; 24.09.2009
comment
Спасибо за размещение кода! Похоже, я был следующим парнем, который пришел искать этот код ... :) - person gehho; 07.07.2010
comment
Я не могу найти Freezable в Silverlight, что мне не хватает? - person kenny; 16.09.2010
comment
@ Kenny - этот код специфичен для WPF. Но посмотрите проект Silverlight MVVM Toolkit на Codeplex. (silverlightmvvm.codeplex.com) Они должны иметь реализацию необходимых командных объектов. - person JMcDaniel; 18.09.2010

ознакомьтесь с этими статьями: http://coderscouch.com/tags/input%20bindings. Они должны быть полезны.

person alvarorahul    schedule 10.04.2013
comment
Взгляните на это: stackoverflow.com/questions/how-to-answer Пожалуйста, не помещайте ссылка в качестве ответа. Объясните, как решить проблему. - person Walery Strauch; 10.04.2013