为什么DateTimePicker不会使用tab键触发keyDown和KeyPress事件?

时间:2017-11-30 12:49:11

标签: vb.net winforms

研究员,我遇到了这个问题 - DateTimePicker不会使用tab键触发KeyDown和KeyPress事件(其他键工作正常,以及keyUp事件,尽管它在&#34之后触发;到达& #34;在按下上一个控件的标签后,在DateTimePicker上聚焦)。我正在使用.net 4.6.1,Visual Basic和VS 2017。

我想做的事情 - > Go to month and year directly on DateTimePicker in C#(直接在DateTimePicker上转到月份和年份)

代码I使用:

Private Sub DateTimePicker1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DateTimePicker1.KeyDown
    If e.KeyCode = Keys.Tab Then
        e.Handled = True
        MsgBox("TAB DOWN")
    End If
End Sub

Private Sub DateTimePicker1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles DateTimePicker1.KeyPress
    e.Handled = True
    MsgBox("tab press")
End Sub

Private Sub DateTimePicker1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DateTimePicker1.KeyUp
    If e.KeyCode = Keys.Tab Then
        MsgBox("TAB UP")
        e.Handled = True
    End If
End Sub

任何线索?

3 个答案:

答案 0 :(得分:3)

Tab键用于导航。将焦点从一个控件移动到另一个控件。因此,您的KeyDown事件处理程序永远不会看到它,键击在此之前被拦截和使用。您可以订阅PreviewKeyDown event并将e.IsInputKey = true设置为变通方法,请检查链接文章中的MSDN示例代码以获取代码。

但无论如何都要使用它是错误的事件,当用户用鼠标而不是键盘改变焦点时,你仍然希望它能够工作。因此,请改用Enter事件。

请注意,这两种方法都存在同样的问题,重点可能已经是之前使用控件的月份部分,因此现在您的代码会错误地将其移动到年份部分。你无法找到哪个部分有焦点,那就是没有好桨的小溪。一个非常丑陋的解决方法是更改​​Format属性,然后返回,强制控件重新创建控件窗口并始终重置焦点。使用BeginInvoke()运行该代码。也许更具建设性,如果您只对月份+年份,CustomFormat属性感兴趣,请考虑不显示当天。

实现焦点攻击的示例代码:

Private Sub DateTimePicker1_Enter(sender As Object, e As EventArgs) Handles DateTimePicker1.Enter
    Me.BeginInvoke(
        New Action(Sub()
                       '' Hack to reset focus
                       DateTimePicker1.Format = DateTimePickerFormat.Long
                       DateTimePicker1.Format = DateTimePickerFormat.Short
                       DateTimePicker1.Focus()
                       SendKeys.Send("{Right}")
                   End Sub))
End Sub

答案 1 :(得分:1)

这个问题不是正确的答案,尽管它也有帮助。如果你想在DateTimePicker内部使标签表现为右键,那么一个好的(粗略)方法是:

Private i = 2

Protected Overrides Function ProcessTabKey(ByVal forward As Boolean) As Boolean
    Dim ctl As Control = Me.ActiveControl
    If ctl IsNot Nothing AndAlso TypeOf ctl Is DateTimePicker And i <> 0 Then
        SendKeys.Send("{Right}")
        i -= 1
        Return True
    End If
    i = 2
    Return MyBase.ProcessTabKey(forward)
End Function

答案 2 :(得分:0)

您需要覆盖ProcessCmdKey功能

Private isTab As Boolean = False

Private isShiftTab As Boolean = False

Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
    If keyData = Keys.Tab Then
        isTab = True
        'Do something with it.
    Else
        isTab = False
    End If

    Return MyBase.ProcessCmdKey(msg, keyData)
End Function