2009-09-23 9 views
10

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

Мой вопрос, что это лучший способ подключить нажатие клавиши на мой взгляд, так что, когда пользователь нажимает Alt + T, связанный объект DelegateCommand обрабатывает его? Подсоединение ярлыка не может быть ТАКОЙ ...

+0

J, Я не могу найти Freezable в Silverlight, что мне не хватает? – kenny

ответ

14

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 исправил эту конкретную проблему, и вам больше не нужно использовать обходной путь статического ресурса. Вы можете ссылаться на команду в своей viewmodel непосредственно из KeyBinding.

+0

Отлично! Мне потребовалось больше времени, чтобы найти класс CommandReference, чем это было для его подключения. Я буквально связывал ключевые привязки в течение двух минут. Благодаря тонну. – JMcDaniel

+0

Я думаю, что оба ответа должны быть объединены, полный ответ на самом деле оба (это и JMcDaniel's). Один не является полным без другого. Мне нужно было решить проблему. Благодаря! – bluediapente

17

Только для справки Класс CommandReference в настоящее время не включен в сборку, которую вы можете ссылаться, но включен в шаблон проекта M-V-VM. Поэтому, если вы не создаете приложение из шаблона, вам нужно получить класс из другого места. Я решил скопировать его из образца проекта. Я включил его ниже, чтобы каждый мог легко получить доступ к этому небольшому фрагменту добра, но обязательно проверьте обновления шаблона в будущих версиях инструментария M-V-VM.

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

Наслаждайтесь!

+1

Эй, спасибо, это будет приятно для следующего парня, который приходит. –

+0

Спасибо, что разместили код! Похоже, что я был «следующим парнем», который пришел, ища этот код ... :) – gehho

+0

Я не могу найти Freezable в Silverlight, что мне не хватает? – kenny

0

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

+1

Пожалуйста, взгляните на это: http://stackoverflow.com/questions/how-to-answer Пожалуйста, не ставьте ссылку в качестве ответа. Объясните, как решить проблему. –

+0

Ссылка не работает, ... – ergohack