2009-09-23 2 views
10

Ich erstelle eine zusammengesetzte Anwendung mit CAL/Prism. Die Hauptregion ist ein Registersteuerelement mit mehreren Arten von Ansichten. Jede Ansicht verfügt über benutzerdefinierte Befehle, mit denen sie umgehen kann und die an Symbolleistenschaltflächen im oberen Bereich des Fensters gebunden sind. Ich habe dies zuvor in nicht-CAL-Anwendungen getan, indem ich einfach die InputBinding für den Befehl festgelegt habe, aber ich konnte keinen solchen Mechanismus im Quellcode für die CAL-Module finden.Wie verknüpfe ich einen Tastendruck mit einem DelegateCommand in Composite WPF?

Meine Frage ist, was ist der beste Weg, um einen Tastendruck meiner Ansicht hook up ist, so dass, wenn der Benutzer drückt Alt + T, das zugehörige DelegateCommand Objekt behandelt es? Das Anschließen einer Verknüpfung kann nicht so schwierig sein ...

+0

J, ich kann Freezable in Silverlight nicht finden, was fehlt mir? – kenny

Antwort

14

Die MVVM Toolkit hat eine Klasse namens CommandReference, die es Ihnen ermöglicht, einen Verweis auf einen Befehl als Tastenkürzel zu verwenden.

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

Das wird es tun.

Bearbeiten: Da dies geschrieben wurde, behoben WPF 4.0 dieses spezielle Problem, und Sie müssen nicht mehr die statische Ressourcenumgehung verwenden. Sie können den Befehl in Ihrem Viewmodel direkt von der KeyBinding referenzieren.

+0

Perfekt! Ich brauchte mehr Zeit, um die CommandReference-Klasse zu finden, als sie zu aktivieren. Ich hatte buchstäblich die Tastenbelegungen innerhalb von zwei Minuten. Danke vielmals. – JMcDaniel

+0

Ich denke, beide Antworten sollten zusammengeführt werden, die vollständige Antwort ist eigentlich beides (dies und JMcDaniel). Einer ist ohne den anderen unvollständig. Ich brauchte beides, um das Problem zu lösen. Vielen Dank! – bluediapente

17

Die Klasse CommandReference ist zur Zeit nicht in einer Assembly enthalten, die Sie referenzieren können, ist aber in der M-V-VM-Projektvorlage enthalten. Wenn Sie also Ihre Anwendung nicht aus der Vorlage erstellen, müssen Sie die Klasse von woanders beziehen. Ich entschied mich, es aus dem Beispielprojekt zu kopieren. Ich habe es unten eingefügt, um jedem den einfachen Zugriff auf diesen kleinen Teil der guten Dinge zu ermöglichen, aber stellen Sie sicher, dass Sie in zukünftigen Versionen des M-V-VM Toolkits nach Updates für die Vorlage suchen.

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

Viel Spaß!

+1

Hey danke, das wird nett für den nächsten Kerl, der mitkommt. –

+0

Danke für das Posten des Codes! Scheint so, als wäre ich "der nächste Typ" der auf der Suche nach diesem Code war ... :) – gehho

+0

Ich kann Freezable in Silverlight nicht finden, was fehlt mir? – kenny

0

Überprüfen Sie diese Artikel: http://coderscouch.com/tags/input%20bindings. Sie sollten hilfreich sein.

+1

Bitte werfen Sie einen Blick auf diese: http://StackOverflow.com/questions/how-to-answer Bitte stellen Sie keinen Link als Antwort. Erklären Sie, wie Sie das Problem lösen können. –

+0

Link ist kaputt, ... – ergohack

Verwandte Themen