2009-09-23 3 views
10

Sto costruendo un'applicazione composita usando CAL/Prism. La regione principale è un controllo a schede, con più tipi di viste al suo interno. Ogni vista ha un comando set personalizzato che può gestire quali sono associati ai pulsanti della barra degli strumenti nella parte superiore della finestra. L'ho già fatto nelle app non CAL semplicemente impostando InputBinding sul comando, ma non sono stato in grado di trovare alcun meccanismo del genere nel codice sorgente per i moduli CAL.Come si associa una pressione di tasto a un DelegateCommand in WPF composito?

La mia domanda è, qual è il modo migliore per collegare una sequenza di tasti a mio punto di vista, in modo che quando l'utente preme Alt +T, l'oggetto DelegateCommand associato lo gestisce? Il collegamento a una scorciatoia non può essere QUELLO difficile ...

+0

J, Non riesco a trovare Freezable in Silverlight, cosa mi manca? – kenny

risposta

14

Il MVVM Toolkit ha una classe denominata CommandReference che consente di utilizzare un riferimento a un comando come una combinazione di tasti.

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

Questo lo farà.

Modifica: Da quando è stato scritto, WPF 4.0 ha risolto questo particolare problema e non è più necessario utilizzare la soluzione alternativa. Puoi fare riferimento al comando nel tuo viewmodel direttamente da KeyBinding.

+0

Perfetto! Mi ci è voluto più tempo per trovare la classe CommandReference di quanto non abbia fatto per collegarlo. Avevo letteralmente fatto funzionare i binding delle chiavi in ​​due minuti. Grazie mille. – JMcDaniel

+0

Penso che entrambe le risposte debbano essere unite, la risposta completa è in realtà entrambe (questa e quella di JMcDaniel). Uno è incompleto senza l'altro. Avevo bisogno di entrambi per risolvere il problema. Grazie! – bluediapente

17

Solo per riferimento, la classe CommandReference non è attualmente inclusa in un assembly a cui è possibile fare riferimento, ma è inclusa nel modello di progetto M-V-VM. Quindi se non costruisci la tua applicazione dal modello, devi ottenere la classe da qualche altra parte. Ho scelto di copiarlo dal progetto di esempio. L'ho incluso qui sotto per consentire a tutti un facile accesso a questo piccolo pezzo di bontà, ma assicurati di controllare gli aggiornamenti del modello nelle future versioni di 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 
} 

Divertiti!

+1

Hey grazie, sarà carino per il prossimo ragazzo che arriva. –

+0

Grazie per aver postato il codice! Sembra che fossi il "prossimo ragazzo" che è arrivato, cercando quel codice ... :) – gehho

+0

Non riesco a trovare Freezable in Silverlight, cosa mi manca? – kenny

0

date un'occhiata a questi articoli: http://coderscouch.com/tags/input%20bindings. Dovrebbero essere d'aiuto.

+1

Si prega di dare un'occhiata a questo: http://stackoverflow.com/questions/how-to-answer Si prega di non inserire un link come risposta. Spiega come risolvere il problema. –

+0

Il collegamento è interrotto, ... – ergohack