How to use the KeyUp event in a UserControl to move the focus

129 views Asked by At

I want to preview Keys directed to child Controls of my UserControl.

Actually what I want is to press the F8 key, to move the focus to a child Control (a TextBox named BtxtBarcode here)

Is there something wrong with the code because I tried with the code below no results.
Please Guide.

Partial Public Class PgItemTransfer
    Inherits UserControl
    Public Sub New()
        If Program.IsInDesignMode(Me) Then
            Return
        End If
        InitializeComponent()
    End Sub
    Private Sub PgItemTransfer_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs) Handles Me.KeyUp
        Try
            Select Case e.KeyCode
                Case Keys.F8
                    BtxtBarcode.Focus()
            End Select
        Catch ex As Exception
            MessageBox.Show(ex.Message, "POS", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        End Try
    End Sub
End

Class

1

There are 1 answers

2
Jimi On BEST ANSWER

To capture a Key press in a UserControl (or other Container Controls), you usually override ProcessCmdKey. This allows to preview the Key press before the message is sent to the intended recipient and, eventually, suppress the Key.
The intended recipient is a child Control of the UserControl, in this case.

I've removed If Program.IsInDesignMode(Me) Then Return from the UserControl's Constructor, because this is clearly not what we want to do there. InitializeComponent() must be called, otherwise the UC becomes unusable

Public Class PgItemTransfer
    Inherits UserControl
    Public Sub New()
        ' Nothing here, we do want to execute InitializeComponent
        InitializeComponent()
    End Sub

    Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
        Select Case keyData
            Case Keys.F8
                BtxtBarcode.Focus()
                ' Return True if you want to suppress the key press
        End Select
        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function
End Class

If you instead want to capture a Key press in any case, e.g., when the focus is on a Control that is not child of this UserControl, but it could be a child of the Form itself, or any other Container, we implement the IMessageFilter interface, then call Application.AddMessageFilter() to activate the feature (of course, also call Application.RemoveMessageFilter() when the UserControl is destroyed or you want to disable this feature)

In this case, whenever you press the F8 key (in this case), the focus is moved to the specified child Control of your UserControl. The currently focused Control can be any Control in a Form

Public Class PgItemTransfer
    Inherits UserControl
    Implements IMessageFilter

    Private Const WM_KEYDOWN As Integer = &H100
    Public Sub New()
        InitializeComponent()
    End Sub

    Public Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
        If m.Msg = WM_KEYDOWN AndAlso m.WParam.ToInt32() = Keys.F8 Then
            BtxtBarcode.Focus()
            ' Return True if you want to suppress the key press
        End If
        Return False
    End Function

    Protected Overrides Sub OnHandleCreated(e As EventArgs)
        MyBase.OnHandleCreated(e)
        If Not DesignMode Then Application.AddMessageFilter(Me)
    End Sub

    Protected Overrides Sub OnHandleDestroyed(e As EventArgs)
        If Not DesignMode Then Application.RemoveMessageFilter(Me)
        MyBase.OnHandleDestroyed(e)
    End Sub
End Class