如���使非模态窗体居中于父窗体

26

我有一个非模态的子窗体,它从一个父窗体中打开。我需要将子窗体居中到其父窗体。我已经将子窗体的属性设置为 CenterParent 并尝试了以下操作:

Form2 f = new Form2();
f.Show(this);

但一无所获。这适用于模态表单,但对非模态表单则不是如此。有简单的解决方案,还是需要我进行所有的数学计算来将其位置修正到中心?


1
你尝试设置了 StartPosition 属性吗? - Daniel A. White
我尝试过了,我在问题中也提到了。对于非模态对话框,它在WinForms中确实无法正常工作。不知道为什么会这样。 - nawfal
你什么时候设置属性? - Daniel A. White
嘿,请恢复您的答案,它真的很有效 :) 我已经在子窗体的设计器中设置了它...但像您说的那样设置确实起作用了...谢谢。 - nawfal
4个回答

65

很抱歉,StartPosition.CenterParent 只适用于模态对话框(.ShowDialog)。
您需要手动设置位置,方法如下:

Form f2 = new Form();
f2.StartPosition = FormStartPosition.Manual;
f2.Location = new Point(this.Location.X + (this.Width - f2.Width) / 2, this.Location.Y + (this.Height - f2.Height) / 2);
f2.Show(this);

谢谢您的快速回答,但我已经在上面以更简单的方式得到了我想要的。 - nawfal
1
由于其他答案不再适用于我,我将把这个标记为答案。 - nawfal
1
请注意,Point类需要 using System.Drawing; - Godsmith

13

在关于窗体居中方面,Show(this) 和 ShowDialog(this) 的行为不同真是很奇怪。我能提供的只有 Rotem 的解决方案,这个方案可以很好地隐藏掉 hacky workaround。

创建一个扩展类:

public static class Extension
{
    public static Form CenterForm(this Form child, Form parent)
    {
        child.StartPosition = FormStartPosition.Manual;
        child.Location = new Point(parent.Location.X + (parent.Width - child.Width) / 2, parent.Location.Y + (parent.Height - child.Height) / 2);
        return child;
    }
}

轻松调用:

var form = new Form();
form.CenterForm(this).Show();

4

对于非模态窗体,这是解决方案。

如果您想在父窗体中心显示一个非模态对话框,则需要将子窗体的StartPosition设置为FormStartPosition.Manual

form.StartPosition = FormStartPosition.Manual;

form.Location = new Point(parent.Location.X + (parent.Width - form.Width) / 2, parent.Location.Y + (parent.Height - form.Height) / 2);

form.Show(parent);

在.NET Framework 4.0中 - 如果将子窗体的ControlBox属性设置为false并将FormBorderStyle属性设置为NotSizable,如下所示:
form.ControlBox = false;
form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;

如果将StartPosition设置为FormStartPosition.Manual,则可能会遇到子窗体部分未显示的问题。

要解决这个问题,您需要将子窗体的Localizable属性设置为true


2
非常感谢。您关于表单的Localizable属性的评论已经解决了一个困扰我很长时间的问题,在一些客户系统上,我的弹出式表单会稍微小一些。这在Microsoft的文档中没有很好地记录。您是否了解为什么它有效以及当Localizable为false时发生了什么?或者知道任何解释它的好链接吗?再次感谢。 - Erik

3
Form2 f = new Form2();
f.StartPosition = FormStartPosition.CenterParent;
f.Show(this);

你知道为什么只有这种方式有效,而不能在子窗体的构造函数中设置centerParent属性吗? - nawfal
4
可以,请问这个对你有用吗?对我不起作用。这段代码在哪里被执行? - Rotem
@kol,是的,很奇怪...对我来说,如果我在设计器中设置子窗体的属性,它不起作用。只有像答案中所示的那样设置,它才能工作。你必须像所示的那样从父窗体设置对象的属性!非常奇怪。 - nawfal
嗯...您在属性编辑器中更改了什么吗? - kol
@kol 我已经做了更改,但我还是回退了。现在它不再起作用了!很奇怪。。 - nawfal
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接