Introduction
Occasionally, the topic comes up of how to detect which control in a WinForm has received focus. Most programmers learn that the form property ActiveControl
typically (more on this later) points to the control with focus on a given form. You could also use a global event handler attached to all form's controls' GotFocus
event as well to gather this information.
However, there is a little known Protected
method that has existed in Container Controls (a form is a container control) since .NET 2.0 that is called UpdateDefaultButton
. This method is called whenever a containercontrol
's ActiveControl
property changes. This change typically is the result of either a mouse or keyboard action, but it may also be set programmatically.
This method can be used as a global GotFocus
event handler as long as you do not programmatically set the ActiveControl
property to a non-focusable control.
Using the Code
How you use this information is up to you. Here is one possible implementation.
In this, I have defined a custom event named FocusChanged
and a custom event argument for the event. The event is raised when form calls the UpdateDefaultButton
method.
Friend Class FocusChangedArg
Inherits EventArgs
Public LastControlWithFocus As Control
Public Sub New(ByVal Last As Control)
LastControlWithFocus = Last
End Sub
End Class
Private LastActiveControl As Control = Me
Friend Event FocusChanged As EventHandler(Of FocusChangedArg)
Protected Overrides Sub UpdateDefaultButton()
RaiseEvent FocusChanged(Me, New FocusChangedArg(LastActiveControl))
LastActiveControl = Me.ActiveControl
End Sub
Private Sub Form1_FocusChanged(ByVal sender As Object, _
ByVal e As FocusChangedArg) Handles Me.FocusChanged
End Sub
Points of Interest
One thing that I discovered is that UpdateDefaultButton
is called before the Click
or DoubleClick
events are fired. Therefore, it is possible to attached their respective handlers in the UpdateDefaultButton
method and if the ActiveControl
changed due to a mouse click, these handlers will then be called.
Protected Overrides Sub UpdateDefaultButton()
RaiseEvent FocusChanged(Me, New FocusChangedArg(LastActiveControl))
If LastActiveControl IsNot Nothing Then
RemoveHandler LastActiveControl.Click, AddressOf anycontrol_Click
RemoveHandler LastActiveControl.DoubleClick, AddressOf anycontrol_DoubleClick
End If
LastActiveControl = Me.ActiveControl
AddHandler LastActiveControl.Click, AddressOf anycontrol_Click
AddHandler LastActiveControl.DoubleClick, AddressOf anycontrol_DoubleClick
End Sub
Private Sub anycontrol_Click(ByVal sender As Object, ByVal e As System.EventArgs)
End Sub
Private Sub anycontrol_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs)
End Sub