วิธีการตรวจหาสถานะตัวดัดแปลงสำคัญใน WPF?


151

มีการสร้างทั่วโลกที่ฉันสามารถใช้เมื่อใดก็ตามที่ฉันต้องการเข้าถึงไม่ว่าจะเป็นปุ่มควบคุม, Shift, Alt หรือไม่ ยกตัวอย่างเช่นภายในกรณีที่มีการMouseDownTreeView

ถ้าเป็นเช่นนั้นได้อย่างไร

คำตอบ:


257

Keyboardระดับการใช้งาน ใช้Keyboard.IsKeyDownคุณสามารถตรวจสอบว่าการควบคุม 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 enum มีแอตทริบิวต์ Flags คุณสามารถมีชุดค่าใด ๆ ใน enum ได้ หากคุณต้องการเพียงกดปุ่ม Shift เท่านั้นให้ใช้Keyboard.Modifiers == ModifierKeys.Shiftคำสั่ง หากคุณต้องการที่จะจับปุ่ม Shift แต่ไม่สนใจว่าตัวดัดแปลงอื่น ๆ ถูกกดในเวลาเดียวกัน(Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shiftหรือใช้ HasFlag หรือไวยากรณ์ที่ดีขึ้นมากKeyboard.Modifiers.HasFlag(ModifierKeys.Shift)
Patrik B

4
ฉันไม่สามารถใช้ตัวแก้ไขคีย์ windows ได้โดยใช้วิธีนี้ (กดปุ่ม CTRL ทำงานดี.) WIN+RightArrowฉันก็พยายามที่จะจับ
Aneves

1
@ANeves น่าสนใจKeyboard.Modifiersแสดงเป็นNone
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;
        }
    }

2
รู้รอบดีกว่าพร้อมคำอธิบายและรหัส โปรดระบุบริบท
คริส

1
ความคิดที่ดีในการเพิ่มเป็น proprerty
RollRoll

1
เมื่อผมใช้ PreviewKeyDown มองหา Alt + กุญแจอีกดอกหนึ่งผมใช้ e.SystemKey แทน e.Key (ค่า e.Key เป็น "ระบบ" ในกรณีของการใช้ Alt + ตัวละครอื่นในกรณีของฉัน)
จอช

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.SystemKey และไม่ใช่แค่ e.Key อาจเป็นเพราะตัวดัดแปลงหรือไม่ แต่สิ่งนี้ทำงานได้อย่างไม่มีที่ติสำหรับฉันเมื่อค้นหาตัวแก้ไข + แป้น



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.