C# 新形式永远不会获得焦点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/853960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# New form never gains focus
提问by
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.
我一直在尝试编写一个带有自己的选项窗口的小应用程序。当我尝试启动窗口时,我似乎永远无法将注意力集中在新表单上。这不是一个 mdi 表单,而只是当用户从菜单中选择一个选项时我创建的一个新表单。需要注意的是 Form.Show 是 return false ,这意味着新表单永远不会获得焦点。
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:
使用旧 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?
有什么建议?
采纳答案by Matt Brunell
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.
显然 Form.Show 和 Form.ShowDialog 之间存在某种幕后差异。不太确定它是什么,我只能认为它与以某种方式设置活动父级有关。在调用构造函数之后添加代码似乎不会将焦点返回给父窗体。它不应该。
回答by Greg D
Have you tried setting the correct parent window in Form.Show()
?
您是否尝试过在 中设置正确的父窗口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?
有一些事情不在你的问题中。您拥有的窗口是 TopMost 窗口吗?
回答by Matt Brunell
Remember that there is only a single user interface thread allowed in a winforms app.
请记住,winforms 应用程序中只允许一个用户界面线程。
Are you manipulating anything on the parent form afteryour call to Form.Show()
? This
may cause the parent form to be focused again.
在调用之后,您是否在父表单上操作任何内容Form.Show()
?这可能会导致父窗体再次获得焦点。
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.
删除您曾经尝试聚焦的所有内容,激活表单并仅依赖于对 的调用Form.Show()
。这应该足以加载表单并专注于它。如果有的话,在您的菜单项处理程序中。在您致电后注释掉所有内容Show()
,看看是否有效。向后工作以查看导致您的父表单重新聚焦的原因。
回答by AnalysX
It's because Form.canFocus()
is false when the form loads. Use Form.Activate()
on Form.Shown
event. That's all.
这是因为Form.canFocus()
表单加载时为 false。Form.Activate()
在Form.Shown
事件中使用。就这样。
private void ServerForm_Shown(object sender, EventArgs e)
{
this.Activate();
}
回答by Gleb Sevruk
Set TopMost
form property to true. Then
将TopMost
表单属性设置为 true。然后
in program.cs:
在 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;
}
回答by Tony Kh
Try to call ShowDialog(this)
. It helped in my case when I faced the same problem.
试着打电话ShowDialog(this)
。当我遇到同样的问题时,它对我有帮助。
回答by bluish
I solved with this (thanks to @Joel Coehoorn):
我解决了这个问题(感谢@Joel Coehoorn):
form.WindowState = FormWindowState.Minimized;
form.Shown += delegate(Object sender, EventArgs e) {
((Form)sender).WindowState = FormWindowState.Normal;
};
form.ShowDialog();