KeyEvents на форме работает только в сочетании с CTRL - PullRequest
0 голосов
/ 08 января 2011

Код:

Private Sub KeyHandling(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    Select Case e.KeyCode
      Case Keys.Left
        btnPrev.PerformClick()
      Case Keys.Right
        btnNext.PerformClick()
      Case Keys.Up
        btnFirst.PerformClick()
      Case Keys.Down
        btnLast.PerformClick()
    End Select
End Sub

Свойство KeyPreview моей формы включено.

Проблема:

Этот код ничего не будет делать, кроме случаев, когда я удерживаюуправляющий ключ.Кто-нибудь может объяснить это?:)

Ответы [ 4 ]

0 голосов
/ 08 января 2011

Это потому, что клавиши курсора перехватываются раньше, до того, как сработает событие KeyDown. Winforms использует его для перемещения фокуса, как Tab. Когда вы удерживаете нажатой клавишу Ctrl, она больше не является навигационной клавишей, и ваше событие KeyDown может ее видеть.

Обычно вы исправляете это, переопределяя IsInputKey (), но это не сработает, если форма имеет какие-либо элементы управления. Они, вероятно, делают, если вы установите KeyPreview в true. Форма никогда не получает фокус, элементы управления делают. В любом случае вам нужно отказаться от KeyPreview, это старый анахронизм VB6, вы ловите клавиши курсора, переопределяя ProcessCmdKey (). Как это:

Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
    If keyData = Keys.Left Then
        Console.WriteLine("left")
        Return True
    End If
    Return MyBase.ProcessCmdKey(msg, keyData)
End Function
0 голосов
/ 08 января 2011

Что происходит, так это то, что клавиши со стрелками перемещаются по элементам управления в форме, подобно клавише Tab . Каждое нажатие клавиши со стрелкой перемещает фокус с текущего активного элемента управления на следующий элемент управления в том же относительном направлении, что и клавиша со стрелкой.

Эта интерпретация клавиш со стрелками реализована на более высоком уровне, чем событие KeyDown формы, которое вы обрабатываете. Каждое нажатие клавиши фактически используется функцией ProcessDialogKey , которая предотвращает передачу этого события клавиши в ваш метод KeyHandling для дальнейшей обработки.

Причина, по которой все работает так, как вы ожидаете, когда удерживается клавиша Ctrl , заключается в том, что функция ProcessDialogKey не использует эти события, что позволяет передавать их в ваш метод-обработчик событий. Документация о методе говорит нам:

Метод не обрабатывает нажатия клавиш, которые включают модификаторы ALT или CONTROL.


Если вы не хотите, чтобы клавиши со стрелками перемещались между вашими элементами управления, и только «нажимали» на кнопки с точно названными именами, решение должно быть очевидным: вам нужно переопределить метод ProcessDialogKey, добавить собственную логику обработки клавиш и верните значение "True", чтобы указать, что вы обработали ключ самостоятельно. В противном случае вы пойдете дальше и вызовете базовый класс, чтобы не нарушать стандартную обработку таких вещей, как Tab и Enter . Опять же, документация здесь очень свежа:

При переопределении метода ProcessDialogKey в производном классе элемент управления должен возвращать true, чтобы указать, что он обработал ключ. Для ключей, которые не обрабатываются элементом управления, должен быть возвращен результат вызова метода ProcessDialogChar базового класса.

Просто добавьте следующий код в вашу форму и удалите метод KeyHandling, который у вас есть сейчас:

Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
    Select Case keyData
        Case Keys.Left
            btnPrev.PerformClick()
            Return True
        Case Keys.Right
            btnNext.PerformClick()
            Return True
        Case Keys.Up
            btnFirst.PerformClick()
            Return True
        Case Keys.Down
            btnLast.PerformClick()
            Return True
    End Select

    Return MyBase.ProcessDialogKey(keyData)
End Function
0 голосов
/ 08 января 2011

Вы должны предоставить гораздо больше информации.

Для начала, какое событие формы вы обрабатываете.Вы показываете обработчик с нестандартным именем обработчика, но не показываете, с каким событием оно связано.Как вы связываете это с событием?

В конструкторе форм посмотрите на вкладку событий в окне Свойства.У вас есть что-нибудь под KeyDown или KeyPress?Вот где он должен быть.

Во-вторых, он ничего не делает, потому что вы не подключили его для формирования событий клавиатуры или потому, что он работает, а просто не делает то, что вы хотите?Установите точку останова.Код когда-нибудь вызывается?

В зависимости от ответа на поставленные выше вопросы, вам может потребоваться переключиться между обработкой события KeyDown или KeyPress, в зависимости от того, какие символы вы пытаетесь обнаружить.

0 голосов
/ 08 января 2011

Я полагаю, у вас есть кнопки в вашей форме.Когда кнопка имеет фокус, пользователь может изменить фокус, перемещаясь с помощью кнопок со стрелками между кнопками в форме.По этой причине кнопки не получают событие KeyDown при нажатии клавиши со стрелкой.

Следующий трюк поможет вам избежать этого.Для каждой кнопки в форме установите для события PreviewKeyDown следующее:

Private Sub Button1_PreviewKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles Button1.PreviewKeyDown
        e.IsInputKey = True
End Sub
...