2009-09-23 4 views
10

CAL/Prism을 사용하여 복합 응용 프로그램을 작성합니다. 메인 영역은 여러 유형의 뷰가있는 탭 컨트롤입니다. 각보기에는 처리 할 수있는 사용자 정의 집합 명령이 있으며,이 명령 집합은 창 상단의 도구 모음 단추에 바인딩됩니다. 이전에 명령에서 InputBinding을 설정하여 비 CAL 응용 프로그램에서이 작업을 수행했지만 CAL 모듈의 소스 코드에서 이러한 메커니즘을 찾을 수 없었습니다.Composite WPF에서 keypress를 DelegateCommand와 연결하려면 어떻게해야합니까?

내 질문은, 내보기에 키 스트로크 (keystroke)를 연결하는 가장 좋은 방법은 무엇이며 사용자가 Alt 키 + T, 관련 DelegateCommand 객체가 처리를 누를 때 그래서? 바로 가기 연결은 그다지 어렵지 않을 수 있습니다 ...

+0

J, Silverlight에서 Freezable을 찾을 수 없습니다. 무엇이 없습니까? – 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에서이 특정 문제가 해결되어 더 이상 정적 리소스 해결 방법을 사용할 필요가 없습니다. ViewBase에서 직접 KeyBinding에서 명령을 참조 할 수 있습니다.

+0

완벽한! CommandReference 클래스를 찾는데 더 많은 시간이 걸렸습니다. 필자는 문자 바인딩을 2 분 만에 수행했습니다. 엄청 고마워. – JMcDaniel

+0

두 답변을 병합해야한다고 생각합니다. 전체 답변은 실제로 둘 다 (this와 JMcDaniel 's)입니다. 하나는 다른 하나가 없으면 불완전합니다. 나는이 문제를 해결하기 위해 둘 다 필요했다. 감사! – bluediapente

17

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 
} 

즐기십시오!

+1

안녕하세요 고마워, 그 다음에 오는 녀석에게 좋을거야. –

+0

코드를 게시 주셔서 감사합니다! 그 코드를 찾는 "다음 사람"처럼 보입니다. :) – gehho

+0

Silverlight에서 Freezable을 찾을 수 없습니다. 무엇이 없습니까? – kenny

0

http://coderscouch.com/tags/input%20bindings을 확인하십시오. 그들은 도움이되어야합니다.

+1

이것 좀보세요 : http://stackoverflow.com/questions/how-to-answer 링크를 답으로 사용하지 마십시오. 문제를 해결하는 방법을 설명하십시오. –

+0

링크가 끊어졌습니다 ... – ergohack