tags:

views:

1959

answers:

5

I have been trying to write a small app with its own option windows. When I try to launch the window I can never seem to set focus on the new form. This is not a mdi form, but merely a new form that I create when a user selects an option from the menu. It should be noted that Form.Show is return false, which means that the new form is never receiving focus.

I have tried multiple methods for loading the form and all have failed:

From Calling Form:

ServerForm SF = new ServerForm(ref DataLoader, false);
SF.Show();
SF.Focus();
// Fails

Inside the form itself:

this.Show();
this.BringToFront();
this.Activate();
this.TopMost = true;
// Fails

Setting Form to selectable:

this.SetStyle(System.Windows.Forms.ControlStyles.Selectable, true);
...
ServerForm SF = new ServerForm(ref DataLoader, false);
SF.Show();
SF.Focus();
// Fails

Using Old API:

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int ShowWindow(IntPtr handle, int nCmdShow);    
ServerForm SF = new ServerForm(ref DataLoader, false);
ShowWindow(SF.Handle, 3);
SF.Show();
SF.Focus();
// Fails

Passing in Parent

ServerForm SF = new ServerForm(ref DataLoader, false);
SF.Show(this);
SF.Focus();
// Fails

In all of these cases the form will show up, but the form that spawned still will have focus over the new form. This happens even when I disable the old form before I create the new form.

Any suggestions?

= Aaron

A: 

Have you tried setting the correct parent window in Form.Show()?

E.g.:

using(ServerForm SF = new ServerForm(ref DataLoader, false)) // if ServerForm is IDisposable
{
    SF.Show(this);
}

Edit:

There's something going on that isn't in your question. Is your owning window a TopMost window?

Greg D
No. Saddly that does not work, but I added it to the list though. Also you can't generate a form using the using keyword as it will kill to form as soon as it goes out of scope.
Ah, yeah, I normally use using with ShowDialog(parent), not Show(parent).
Greg D
A: 

Remember that there is only a single user interface thread allowed in a winforms app.

Are you manipulating anything on the parent form after your call to Form.Show()? This may cause the parent form to be focused again.

Remove everything you have used to try to focus, activate the form and rely just on the call to Form.Show(). This should be enough to load the form, and focus upon it. If anything, in your menu item handler. Comment out everything after your call to Show() and see if that works. Work backwards to see what caused your parent form to be refocused.

Matt Brunell
There is nothing after this Form.Show in the call. The thing is that the Form.Show itself is not returning true. Its not like the form is temporarily gain focus. Its never getting focus in the first place.
A: 

This seems to work. First I create the new form:

private void changeDefaultServerToolStripMenuItem_Click(object sender, EventArgs e)
{
    this.Enabled = false;
    ServerForm SF = new ServerForm(ref DataLoader, true);
}

Then in the constructor for the new form I do the following:

this.BringToFront();
this.CenterToParent();
this.TopMost = true;
this.ShowDialog();

Apparently there is some sort of behind the scene difference between Form.Show and Form.ShowDialog. Not quites sure what it is, I can only think it has to do with setting the active parent somehow. Adding code after the call to construct the function does not seem to give back focus to the parent form. Which it shouldn't.

Why are you making it TopMost? You shouldn't do that unless there's a really compelling reason. Also, the constructed form generally shouldn't call Show on itself like that.
Greg D
The difference between Show and ShowDialog is that ShowDialog displays a modal dialog. You should always specify the parent with ShowDialog() unless there's no parent to specify.
Greg D
I added TopMost because I wanted to ensure it showed up on top. Is it always needed? No. However, it ensures it occurs when it might not.
It also assures it stays on top when the user wants the window in the background. Don't use TopMost unless you must. As a user, I know I get _very_ peeved with software that abuses TopMost. Sufficiently that I won't buy software from the company that made it, given a choice.
Greg D
A: 

It's because Form.canFocus() is false when the form loads. Use Form.Activate() on Form.Shown event. That's all.

private void ServerForm_Shown(object sender, EventArgs e)
{
    this.Activate();
}
AnalysX
A: 

Set TopMost of form property to true. Then

in program.cs:

    var formLogin = new frmLogin();
    formLogin.ShowDialog();


    if (formLogin.DialogResult == DialogResult.Yes)
    {
            Application.Run(new frmMain());
    }

in formLogin:

    [DllImport("user32")]
    public static extern int SetForegroundWindow(IntPtr hwnd);         

    ...

    private void frmLogin_Shown(object sender, EventArgs e)
    {
      SetForegroundWindow(this.Handle);
    }

    private void frmLogin_Deactivate(object sender, EventArgs e)
    {
        TopMost = false;

    }
Gleb Sevruk