2009-09-23 11 views
10

Buduję złożoną aplikację przy użyciu CAL/Prism. Główny region to kontrolka tabulacji z wieloma typami widoków. Każdy widok ma niestandardowe polecenia, które może obsłużyć, które są powiązane z przyciskami paska narzędzi w górnej części okna. Zrobiłem to wcześniej w aplikacjach innych niż CAL, po prostu ustawiając InputBinding na komendzie, ale nie byłem w stanie znaleźć takiego mechanizmu w kodzie źródłowym dla modułów CAL.Jak powiązać naciśnięcie klawisza z komendą DelegateCommand w złożonym WPF?

Moje pytanie brzmi, co jest najlepszym sposobem, aby podłączyć się do klawiszy, moim zdaniem, tak, że gdy użytkownik naciśnie alt + firmy T, powiązany DelegateCommand obiekt obsługuje go? Podłączanie skrótu nie może być TAK trudne ...

+0

J, Nie mogę znaleźć Freezable w Silverlight, czego mi brakuje? – kenny

Odpowiedz

14

Urządzenie MVVM Toolkit ma klasę o nazwie CommandReference, która umożliwia użycie odwołania do polecenia jako klawisza dostępu.

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

To wystarczy.

Edit: Ponieważ ten został napisany, WPF 4.0 ustalona ten konkretny problem i nie trzeba już używać statycznego obejścia zasobów. Możesz odwołać się do polecenia w swoim viewmodelu bezpośrednio z KeyBinding.

+0

Idealny! Znalezienie klasy CommandReference zajęło mi więcej czasu niż po to, żeby ją podłączyć. Dosłownie za dwa minuty miałem przypisane klawisze. Dzięki za tonę. – JMcDaniel

+0

Myślę, że obie odpowiedzi powinny zostać połączone, pełna odpowiedź jest w rzeczywistości zarówno (ta i JMcDaniel's). Jeden jest niepełny bez drugiego. Potrzebowałem obu, aby rozwiązać problem. Dzięki! – bluediapente

17

Dla odniesienia, klasa CommandReference nie jest obecnie uwzględniona w zespole, do którego można się odwoływać, ale jest dołączona do szablonu projektu M-V-VM. Jeśli więc nie budujesz swojej aplikacji z szablonu, musisz przenieść klasę z innego miejsca. Zdecydowałem się skopiować go z przykładowego projektu. Zawarłem to poniżej, aby umożliwić każdemu łatwy dostęp do tego małego kawałka dobroci, ale koniecznie sprawdź aktualizacje szablonu w przyszłych wersjach 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 
} 

Ciesz się!

+1

Hej dziękuję, to będzie miłe dla następnego faceta, który przyjdzie. –

+0

Dzięki za napisanie kodu! Wygląda na to, że byłem "kolejnym facetem", który pojawił się, szukając tego kodu ... :) – gehho

+0

Nie mogę znaleźć Freezable w Silverlight, czego mi brakuje? – kenny