Search code examples
vb.netwinformsuser-controlsfocuskeyup

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


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


Solution

  • 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