I had the same issue in Windows Forms and vb.net (it can be probably easily converted to c#) and I solved it in the following way:
1. Set the form KeyPreview property to true.
Gets or sets a value indicating whether the form will receive key events before the event is passed to the control that has focus.
This allows you to handle key events only for the form instead of for every textbox. Obviously if you have only one textbox this will save you no work.
2. Handle the form KeyUp event
It looks like the KeyDown and KeyPressed events do not fire for the Tab key, but unexpectedly, the KeyUp does...
I leave you the code I used on the KeyUp event:
Private Sub MyForm_KeyUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyUp
// Do nothing if key other than TAB is pressed
If Not e.KeyCode = Keys.Tab Then Exit Sub
// Search for the control that currently has the focus
// As we are only interested in doing something when the focus is in textboxes, we do not even search the focus for other controls
Dim focused_textbox As TextBox = Nothing
For Each p As TextBox In GetAllTextBoxes(Me) //GetAllTextBoxes is a function that gets a list with all the textboxes for the form passed as a parameter.
If p.Focused Then
focused_textbox = p
Exit For
End If
Next
// If no textbox has the focus, no actions are required.
If focused_textbox Is Nothing Then Exit Sub
// If the textbox with the focus does not have any content, nothing is to be selected....
If String.IsNullOrEmpty(focused_textbox.Text) Then Exit Sub
// select all the textbox contents
focused_textbox.SelectAll()
/* I've also seen arroun the following sollution, instead of the 'focused_textbox.SelectAll()', but I have not tried it, as SelectAll worked perfect for me
focused_textbox.SelectionStart = 0
focused_textbox.SelectionLength = focused_textbox.Text.Length
*/
End Sub
I also give you my 'GetAllTextBoxes' function, it might probably not be the most efficient way but it works.
Function GetAllTextBoxes(ByVal control_or_form As Object) As List(Of TextBox)
Dim l As List(Of TextBox) = New List(Of TextBox)
// Fill control_collection with child controls of the control_or_form
Dim control_collection As List(Of Control) = New List(Of Control)
If TypeOf control_or_form Is Windows.Forms.Form Then
Dim form As Windows.Forms.Form = CType(control_or_form, Windows.Forms.Form)
If form.HasChildren Then
For Each c As Control In form.Controls
control_collection.Add(c)
Next
Else
Return l
End If
ElseIf TypeOf control_or_form Is Windows.Forms.Control Then
Dim control As Windows.Forms.Control = CType(control_or_form, Windows.Forms.Control)
If control.HasChildren Then
For Each c As Control In control.Controls
control_collection.Add(c)
Next
Else
Return l
End If
Else
Return l
End If
// At this point if control_or_form is not a control or a form, or if it has no children, the function had already returned an empty list meaning 'this object has no child textboxes'
// Now, for all the child controls, store them into the list if they are TextBoxes and, if not, search more TextBoxes within its childs if it has any.
For Each child_c As Control In control_collection
If TypeOf child_c Is TextBox Then
l.Add(child_c)
End If
If child_c.HasChildren Then
l.AddRange(GetAllTextBoxes(child_c)) //Here we see why this function needs to allow input form and control at the same time
End If
Next
Return l
End Function
Hope this helps somebody ;)