WPFで修飾キーの状態を検出する方法は?


151

Control、Shift、Altボタンが押されているかどうかにアクセスする必要があるときにいつでも使用できるグローバル構造はありますか?例えば中MouseDownイベントTreeView

もしそうなら?

回答:


257

クラスを使用しKeyboardます。を使用しKeyboard.IsKeyDownて、Ctrl、Shift、Altが現在ダウンしているかどうかを確認できます。

シフトの場合:

if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{ /* Your code */ }

コントロール:

if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{ /* Your code */ }

Altの場合:

if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{ /* Your code */ }

125

またあります:

// Have to get this value before opening a dialog, or user will have released the control key
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{

}

13
はるかに優れたソリューション。また、すべての修飾子を一度にチェックすることもできます。Ctrl + Fを処理したい場合、Ctrl + Shift + Fを処理したくないので(e.Key == Key.F && e.KeyboardDevice.Modifiers == ModifierKeys.Control)、他のすべてのものの代わりにチェックするだけです...
ygoe

35
上記の例の比較では異なる結果が得られることに注意してください!ModifierKeys列挙にはFlags属性があるため、列挙内の値の任意の組み合わせを使用できます。押されているシフトキーだけをキャッチする場合は、Keyboard.Modifiers == ModifierKeys.Shiftステートメントを使用します。Shiftキーをキャッチしたいが他の修飾子が同時に押されても気にしない場合は、(Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.ShiftHasFlag構文またはそれ以上の構文を使用してくださいKeyboard.Modifiers.HasFlag(ModifierKeys.Shift)
Patrik B

4
この方法では、Windowsキー修飾子を取得できませんでした。(CTRLは正常に動作しました。)キャッチしようとしていましたWIN+RightArrow
ANeves 2014年

1
@ANeves興味深い、次のKeyboard.Modifiersように表示None
チャック・サベージ

8
    private bool IsShiftKey { get; set; }

    private void OnPreviewKeyDown(object sender, KeyEventArgs e)
    {
        IsShiftKey = Keyboard.Modifiers == ModifierKeys.Shift ? true : false;

        if ((Key.Oem3 == e.Key || ((IsShiftKey && Key.Oem4 == e.Key) || (IsShiftKey && Key.Oem6 == e.Key) || (IsShiftKey && Key.Oem5 == e.Key)) && (validatorDefn as FormatValidatorDefinition).format == "packedascii"))
        {
           e.Handled = true;
        }
    }

2
解答は、コメントだけでなくコードでも優れています。いくつかのコンテキストを提供してください。
Chris

1
プロパティとして追加するという素晴らしいアイデア
RollRoll

1
PreviewKeyDownを使用してAlt +別のキーを探したとき、e.Keyではなくe.SystemKeyを使用する必要がありました(e.Keyの値は、私の場合はalt + another文字を使用する場合は「System」でした)
Josh

3

これが(PreviewKeyDownを使用して)処理する方法です。たとえば、Alt + Rを探しているとします...

private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)
       && e.SystemKey == Key.R)
    {
       //do whatever
    }
}

多分修飾子が原因で、なぜe.Keyだけでなくe.SystemKeyを使用しなければならなかったのか、誰かが解決できるかもしれません。しかし、修飾子+キーを検索するときに、これは完璧に機能しました。


0

そして同様に:

もしMy.Computer.Keyboard.ShiftKeyDownなら...

My.Computer.Keyboard.CtrlKeyDown

My.Computer.Keyboard.AltKeyDown


0

@Joshから一部借用し、@ Krushikにいくらか類似しており、KeyEventArgs.systemKeyとKeyEventArgs.Keyの違いに関する質問も参照しています(JoshがSystemKeyを使用する必要がある理由に回答)。ここで、修飾キー(Altなど)を使用すると、e.KeyはKey.Systemを返すため、「実際の」キーはe.SystemKey内にあります。

これを回避する方法は、最初に「実際の」キーをフェッチしてから、条件を実行することです。

private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    // Fetch the real key.
    var key = e.Key == Key.System ? e.SystemKey : e.Key;

    if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
        && key == Key.Return)
    {
        // Execute your code.
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.