Bagaimana mendeteksi status kunci pengubah di WPF?

151

Apakah ada beberapa konstruksi global yang dapat saya gunakan setiap kali saya perlu mengakses apakah tombol Control, Shift, Alt sedang down? Misalnya di dalam MouseDownacara a TreeView.

Kalau begitu bagaimana?

Joan Venge
sumber

Jawaban:

257

Gunakan kelas Keyboard. Menggunakan Keyboard.IsKeyDownAnda dapat memeriksa apakah Control, Shift, Alt turun sekarang.

Untuk Shift:

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

Untuk Kontrol:

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

Untuk Alt:

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

Ada juga:

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

}
Chuck Savage
sumber
13
Solusi yang jauh lebih baik. Ini juga memungkinkan Anda untuk memeriksa semua pengubah sekaligus. Jika Anda ingin menangani Ctrl + F, Anda tidak akan ingin menangani Ctrl + Shift + F, jadi Anda bisa memeriksa (e.Key == Key.F && e.KeyboardDevice.Modifiers == ModifierKeys.Control)alih - alih semua hal lainnya ...
ygoe
35
Perhatikan bahwa perbandingan dalam contoh di atas menghasilkan hasil yang berbeda! Karena ModifierKeys enum memiliki atribut Flags, Anda dapat memiliki kombinasi nilai apa pun di enum. Jika Anda ingin menangkap HANYA tombol shift ditekan, gunakan Keyboard.Modifiers == ModifierKeys.Shiftpernyataan. Jika Anda ingin menangkap tombol shift tetapi tidak peduli apakah pengubah lain ditekan pada saat yang sama, gunakan (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shiftsintaks HasFlag atau yang jauh lebih baikKeyboard.Modifiers.HasFlag(ModifierKeys.Shift)
Patrik B
4
Saya tidak dapat menangkap pengubah kunci windows menggunakan metode ini. (CTRL bekerja dengan baik.) Saya mencoba menangkap WIN+RightArrow.
ANeves
1
@ ANeves Interesting, Keyboard.Modifierstampil sebagaiNone
Chuck Savage
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;
        }
    }
Krushik
sumber
2
Jawaban lebih baik dengan komentar maupun kode. Tolong berikan beberapa konteks.
Chris
1
ide bagus untuk menambahkannya sebagai properti
RollRoll
1
Ketika saya menggunakan PreviewKeyDown mencari Alt + kunci lain saya harus menggunakan e.SystemKey bukannya e.Key (nilai e.Key adalah "Sistem" dalam kasus menggunakan alt + karakter lain, dalam kasus saya)
Josh
3

Ini adalah bagaimana saya menanganinya (menggunakan PreviewKeyDown), katakanlah kita mencari Alt + R ...

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

Mungkin seseorang dapat menjelaskan mengapa saya harus menggunakan e.SystemKey dan bukan hanya e.Key, mungkin karena pengubahnya? tapi ini berhasil bagi saya ketika mencari kunci pengubah +.

Josh
sumber
0

dan juga:

jika My.Computer.Keyboard.ShiftKeyDown maka ...

My.Computer.Keyboard.CtrlKeyDown

My.Computer.Keyboard.AltKeyDown

rampok
sumber
0

Sebagian meminjam dari @Josh, dan agak mirip dengan @Krushik, dan juga merujuk pertanyaan tentang Perbedaan antara KeyEventArgs.systemKey dan KeyEventArgs.Key (menjawab mengapa Josh harus menggunakan SystemKey); di mana, dengan kunci pengubah (seperti Alt), e.Key mengembalikan Key.System, dan dengan demikian kunci 'asli' ada dalam e.SystemKey.

Cara untuk mengatasi ini, adalah dengan terlebih dahulu mengambil kunci 'asli', dan kemudian lakukan kondisional Anda:

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.
    }
}
Elliot
sumber