2017-01-26 22 views
0

WPFでは、ViewModelで簡単にコマンドとコマンドハンドラを作成し、標準のMVVMデザインパターンに従って、XAML(View)のButtonコントロールに簡単に接続できます。また、XAML(View)でInputBindingsとCommandBindingsを定義して、キーダウンを処理してViewModelでコマンドを実行することもできます。 現在ボタン上に1つのコマンドがあり、ボタンをクリックすると実行されます。 しかし、同時にボタンをクリックしてキーの変更を押しても別のコマンドを実行するにはどうすればいいですか?キー変更子は、左または右のAltキーになります。WPFボタンキーダウンでXAML/MVVMのクリックコマンドを変更

答えて

0

押されたキーはフォーカスされたWPF要素からのみ読み込むことができます。あなたの場合、あなたは窓からそれを得ることができます(ページ)。

XAML

<Window x:Class="Application.MainWindow" 
    mc:Ignorable="d" 
    Title="MainWindow" 
    KeyDown="MainWindow_OnKeyDown" 
    x:Name="RootKey"> 

コードビハインド

private void MainWindow_OnKeyDown(object sender, KeyEventArgs e) 
{ 
    var dataContext = (MainPageViewModel) this.DataContext; 
    dataContext.KeyModifer = e.SystemKey.ToString(); 
} 

のViewModel

internal class MainPageViewModel : ViewModelBase 
{ 
    public string KeyModifer { private get; set;} 
    ... 
} 
+0

おかげで、これは私も何かあります結論づけられた。 ViewModelでプロパティをリセットするためにWindow上にKeyUpハンドラを追加していたにもかかわらず、ビューはファイルのコードの中のプロパティを直接変更するので、これはMVVMパターンを破ります。これはメインアプリケーションウィンドウに入れておく必要があります。これは非常に複雑ですが、MVVMパターンに従っていたいと思っていたように、メンテナンスとエレガントではありません...しかし、それ以外の方法では解決できない場合私はそれを残しておく必要があります... – VladacusB

0

以下の入力結合の例に修飾プロパティを設定することで、XAMLでこれを行います。

<TextBox.InputBindings> 
    <KeyBinding Key="Enter" Command="{Binding SaveCommand}" Modifiers="Alt"/> 
    <KeyBinding Key="Enter" Command="{Binding AnotherSaveCommand}"/> 
</TextBox.InputBindings> 
+0

これは、マウスではなく2つのキーを使用すると正常に動作します。マウスのクリック+キーを押しながら別のコマンドを実行するにはどうしたらいいですか? VladacusB

1

あなたは、添付の動作を実現することができます。

namespace WpfApplication1 
{ 
    public class CombinedMouseAndKeyCommandBehavior 
    { 
     public static readonly DependencyProperty KeyProperty = DependencyProperty.RegisterAttached("Key", typeof(Key), 
      typeof(CombinedMouseAndKeyCommandBehavior), new PropertyMetadata(Key.None, new PropertyChangedCallback(OnKeySet))); 

     public static Key GetKey(FrameworkElement element) => (Key)element.GetValue(KeyProperty); 

     public static void SetKey(FrameworkElement element, Key value) => element.SetValue(KeyProperty, value); 

     public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand), 
      typeof(CombinedMouseAndKeyCommandBehavior), new PropertyMetadata(null)); 

     public static ICommand GetCommand(FrameworkElement element) => (ICommand)element.GetValue(CommandProperty); 

     public static void SetCommand(FrameworkElement element, ICommand value) => element.SetValue(CommandProperty, value); 

     private static void OnKeySet(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement fe = d as FrameworkElement; 
      fe.PreviewMouseLeftButtonDown += Fe_PreviewMouseLeftButtonDown; 
     } 

     private static void Fe_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
     { 
      FrameworkElement fe = sender as FrameworkElement; 
      Key key = GetKey(fe); 
      ICommand command = GetCommand(fe); 
      if(key != Key.None && command != null && Keyboard.IsKeyDown(key)) 
      { 
       command.Execute(null); 
      } 
     } 
    } 
} 

使用法:

<Button Content="Test command" 
       xmlns:local="clr-namespace:WpfApplication1" 
       local:CombinedMouseAndKeyCommandBehavior.Command="{Binding RemoveCommand}" 
       local:CombinedMouseAndKeyCommandBehavior.Key="F"> 
    <Button.InputBindings> 
     <MouseBinding Gesture="LeftClick" Command="{Binding AddCommand }" /> 
    </Button.InputBindings> 
</Button> 

はじめWPFでの添付行動へ:https://www.codeproject.com/Articles/28959/Introduction-to-Attached-Behaviors-in-WPF

関連する問題