Form focus issue...

ALX

Well-known member
Joined
Nov 16, 2005
Messages
253
Location
Columbia, SC
Programming Experience
10+
I have Form1 that displays Form2, in a non-modal format, within Form1's layout. When the user clicks on a control or label on Form2, the focus, of course, shifts to Form2. I want to get the focus back to Form1 without making the user click on Form1 so that any subsequent key presses can be processed by Form1 rather than Form2. Surely there must be a simple way to do this but it is alluding me...... ???
 
All key presses for the child form go through the parent first. Just set the KeyPreview property of the parent form to True and it will raise KeyDown, KeyPress and KeyUp events for all keys before the child form, which in turn will raise them before the control with focus.
 
That's interesting... right now I have to manually click on form1 to get it to respond to any keydown events. 'Guess I'll have to take a closer look at my code if it is supposed to work like that. I DO have KeyPreview for Form1 set to TRUE and have even tried setting KeyPreview for Form2 to TRUE in attempts to get this thing to work..
Following is a ridiculously trite example of what I cannot get to work.
VB.NET:
[SIZE=2][COLOR=#0000ff]Public[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Class[/COLOR][/SIZE][SIZE=2] Form1[/SIZE]
[SIZE=2][COLOR=#0000ff]Friend[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]WithEvents[/COLOR][/SIZE][SIZE=2] frm2 [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] Form2[/SIZE]
 
[SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] Form1_Load([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Object[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].Load[/SIZE]
[SIZE=2]   frm2 = [SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] Form2[/SIZE][/SIZE]
[SIZE=2]   [SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].AddOwnedForm(frm2)[/SIZE]
[SIZE=2]   frm2.Location = [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] Point([/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].Location.X + 20, [/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].Location.Y + 20)[/SIZE]
[SIZE=2]   frm2.BringToFront()[/SIZE]
[SIZE=2]   frm2.Show()[/SIZE]
[/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] Form1_KeyDown([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Object[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Windows.Forms.KeyEventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].KeyDown[/SIZE]
    [SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=2] e.KeyCode = Keys.Escape [/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[COLOR=#0000ff]        [/COLOR][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].BackColor = Color.White [/SIZE][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[COLOR=#0000ff]            [/COLOR][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].BackColor = Color.Black[/SIZE]
        [SIZE=2][COLOR=#0000ff]Else[/COLOR][/SIZE]
[COLOR=#0000ff]            [/COLOR][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].BackColor = Color.White[/SIZE]
        [SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[COLOR=#0000ff]    [/COLOR][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Class[/COLOR][/SIZE]

Prior to clicking on frm2, pressing the ESCAPE key alternates the background color of form1. If frm2 has a label or button, clicking it will shift focus to frm2. After that, the keydown for frm1 no longer works until the user clicks form1 to regain focus.
 
Last edited:
Try this. Create a brand new project. In the default form change the KeyPreview and IsMdiContainer properties to True. Now add a second form and add a TextBox to that form. Accept the default names for both. In the first form place this code:
VB.NET:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim f2 As New Form2

    f2.MdiParent = Me
    f2.Show()
End Sub

Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
    Console.WriteLine("Form1_KeyPress")
End Sub
In the second form set the KeyPreview property to True and add this code:
VB.NET:
Private Sub Form2_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
    Console.WriteLine("Form2_KeyPress")
End Sub

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
    Console.WriteLine("TextBox1_KeyPress")
End Sub
Now run your project, press a key and loo at the Output window. When I did that I got this:
Form2_KeyPress
Form1_KeyPress
TextBox1_KeyPress
The form's raise the event in the opposite order to what I originally stated but they both very definitely raise the event.

if you're not getting that result in your current project then either you're doing something wrong or it has something to do with how you're displaying the child form. To know that we'd have to know exactly what you're doing. Explain how we can reproduce the issue you mention.
 
Hmmm... I'm not sure why I assumed that you were using an MDI because looking back at your first post there's nothing to indicate that you were. Sorry about that. If that's a more appropriate setup for your app then I guess i helped despite myself. Otherwise sorry for leading you astray.
 
If you want the caller to have focus after displaying the dialogue then just focus it. You focus a form programmatically by calling its Activate method.
VB.NET:
Dim f As New Form

f.Show()
Me.Activate()
 
Actually, let me change that code just a little:
VB.NET:
Dim f As New Form

f.Show(Me)
Me.Activate()
Note that passing 'Me' to Show makes the current form the owner of the new form. Neater than calling AddOwnedForm.
 
Back
Top