C#新形式从未获得焦点

时间:2009-05-12 17:40:41

标签: c# forms focus

我一直在尝试用自己的选项窗口编写一个小应用程序。当我尝试启动窗口时,我似乎无法将注意力集中在新窗体上。这不是mdi表单,而只是我在用户从菜单中选择选项时创建的新表单。应该注意的是,Form.Show返回false,这意味着新表单永远不会获得焦点。

我尝试了多种加载表单的方法,但都失败了:

来自致电表格:

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

表单内部:

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

将表单设置为可选:

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

使用旧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

传递父母

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

在所有这些情况下,表单都会显示,但生成的表单仍然会关注新表单。即使我在创建新表单之前禁用旧表单,也会发生这种情况。

有什么建议吗?

7 个答案:

答案 0 :(得分:10)

这是因为表单加载时Form.canFocus()为false。在Form.Activate()活动中使用Form.Shown。就是这样。

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

答案 1 :(得分:1)

TopMost表单属性设置为true。然后

在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;

}

答案 2 :(得分:1)

我解决了这个问题(感谢@Joel Coehoorn):

form.WindowState = FormWindowState.Minimized;
form.Shown += delegate(Object sender, EventArgs e) {
    ((Form)sender).WindowState = FormWindowState.Normal;
};
form.ShowDialog();

答案 3 :(得分:0)

请记住,winforms应用程序中只允许使用一个用户界面线程。

在您致电Form.Show()之后,您是否正在操作父表单上的任何内容?这个 可能会导致父表单再次聚焦。

删除您尝试关注的所有内容,激活表单并仅依靠对Form.Show()的调用。这应该足以加载表单,并专注于它。如果有的话,在你的菜单项处理程序中。在致电Show()后注释掉所有内容,看看是否有效。向后工作以查看是什么原因导致您的父表单重新聚焦。

答案 4 :(得分:0)

这似乎有效。首先,我创建新表单:

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

然后在新表单的构造函数中,我执行以下操作:

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

显然,Form.Show和Form.ShowDialog之间存在某种幕后差异。不确定它是什么,我只能认为它与以某种方式设置活动父母有关。在调用构造函数之后添加代码似乎不会将焦点重新放回父窗体。不应该这样。

答案 5 :(得分:0)

尝试拨打ShowDialog(this)。当我遇到同样的问题时,它对我的​​情况有帮助。

答案 6 :(得分:-1)

您是否尝试在Form.Show()中设置正确的父窗口?

E.g:

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

编辑:

正在发生的事情不在您的问题中。您拥有的窗口是TopMost窗口吗?