VB.Net обнаруживать нажатие клавиши на элементе управления перед нажатием клавиши на событии формы

#vb.net

#vb.net

Вопрос:

Я включил опцию KeyPreview в форме, и при нажатии клавиши формы я обнаруживаю нажатие клавиши Escape для всплывающего сообщения с запросом, хочет ли пользователь выйти из приложения.

Но проблема в том, что у меня есть одно текстовое поле, которое должно очищать свое содержимое при нажатии клавиши Escape, а не спрашивать, нужно ли пользователю выходить. И я попытался использовать событие нажатия клавиши для этого элемента управления, но событие нажатия клавиши формы происходит до нажатия клавиши управления (я хочу, чтобы это произошло наоборот).

Код в текстовом поле

     Private Sub txtAmount(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtAmount.KeyDown
        If e.KeyCode = Keys.Escape Then
            '//Escape keypress
            MsgBox("TEXTBOX ESCAPE")
            sender.Text = ""
        End If
    End Sub
  

Код, используемый в форме главного меню

     Private Sub frmMainMenu_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If e.KeyCode = Keys.Escape Then Application.Exit()
    End Sub
  

Я также не могу использовать previewkeydown, потому что MaskTextBox не вызывает событие previewkeydown..

Ответ №1:

Проверьте, сфокусирован ли txtAmount в Form_KeyDown:

     Private Sub txtAmount_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles txtAmount.KeyDown
        If e.KeyCode = Keys.Escape Then
            '//Escape keypress
            MsgBox("TEXTBOX ESCAPE")
            sender.Text = ""
        End If
    End Sub

    Private Sub frmMainMenu_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If txtAmount.Focused Then Return
        If e.KeyCode = Keys.Escape Then Application.Exit()
    End Sub
  

Редактировать: В качестве альтернативы, если вы не хотите указывать каждый элемент управления по отдельности, вы могли бы сделать это по типу:

     If TypeOf Me.ActiveControl Is MaskTextBox Then Return
  

Или, что еще проще, измените ваше Form_KeyDown-событие на событие KeyUp.

 Public Class frmMainMenu
    Private KeyHandled As Boolean

    Private Sub txtAmount_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles txtAmount.KeyDown
        If e.KeyCode = Keys.Escape Then
            sender.Text = ""
            KeyHandled = True
        End If
    End Sub

    Private Sub frmMainMenu_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        KeyHandled = False
    End Sub

    Private Sub frmMainMenu_KeyUp(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
        If KeyHandled Then Return
        If e.KeyCode = Keys.Escape Then Application.Exit()
    End Sub

End Class
  

Комментарии:

1. нет ли лучшего решения для этой проблемы .. потому что мне пришлось бы добавить все элементы управления, которые будут пропущены в моем frmMainMenu keydown..

2. Решение с .Focused = True позволяет мне явно указать места, где горячая клавиша НЕ должна выполняться. Спасибо за эту идею @dummy

Ответ №2:

Вот мой код

 Private Sub When_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown, MyBase.KeyDown
    If sender.name = "Your form name" Then
        If e.KeyCode = Keys.Escape And Not TextBox1.Focused Then
            MsgBox("me")
        End If
    ElseIf sender.name = "your textBox name" Then
        If e.KeyCode = Keys.Escape Then
            MsgBox("txt")
        End If
    End If
End Sub
  

Я надеюсь, что это может вам помочь