FormStartPosition.CenterParent 不起作用
在下面的代码中,只有第二种方法适合我(.NET 4.0)。 FormStartPosition.CenterParent
不会使子窗体在其父窗体上居中。 为什么?
资料来源:这个问题
using System;
using System.Drawing;
using System.Windows.Forms;
class Program
{
private static Form f1;
public static void Main()
{
f1 = new Form() { Width = 640, Height = 480 };
f1.MouseClick += f1_MouseClick;
Application.Run(f1);
}
static void f1_MouseClick(object sender, MouseEventArgs e)
{
Form f2 = new Form() { Width = 400, Height = 300 };
switch (e.Button)
{
case MouseButtons.Left:
{
// 1st method
f2.StartPosition = FormStartPosition.CenterParent;
break;
}
case MouseButtons.Right:
{
// 2nd method
f2.StartPosition = FormStartPosition.Manual;
f2.Location = new Point(
f1.Location.X + (f1.Width - f2.Width) / 2,
f1.Location.Y + (f1.Height - f2.Height) / 2
);
break;
}
}
f2.Show(f1);
}
}
In the following code, only the second method works for me (.NET 4.0). FormStartPosition.CenterParent
does not center the child form over its parent.
Why?
Source: this SO question
using System;
using System.Drawing;
using System.Windows.Forms;
class Program
{
private static Form f1;
public static void Main()
{
f1 = new Form() { Width = 640, Height = 480 };
f1.MouseClick += f1_MouseClick;
Application.Run(f1);
}
static void f1_MouseClick(object sender, MouseEventArgs e)
{
Form f2 = new Form() { Width = 400, Height = 300 };
switch (e.Button)
{
case MouseButtons.Left:
{
// 1st method
f2.StartPosition = FormStartPosition.CenterParent;
break;
}
case MouseButtons.Right:
{
// 2nd method
f2.StartPosition = FormStartPosition.Manual;
f2.Location = new Point(
f1.Location.X + (f1.Width - f2.Width) / 2,
f1.Location.Y + (f1.Height - f2.Height) / 2
);
break;
}
}
f2.Show(f1);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
这是因为您没有告诉
f2
它的Parent
是谁。如果这是 MDI 应用程序,则
f2
应将其MdiParent
设置为f1
。如果这不是 MDI 应用程序,则需要使用
f1
作为参数来调用ShowDialog
方法。请注意,
CenterParent
无法与Show
一起正常工作,因为无法设置Parent
,因此如果ShowDialog
不合适,手动方法是唯一可行的方法。This is because you are not telling
f2
who itsParent
is.If this is an MDI application, then
f2
should have itsMdiParent
set tof1
.If this is not an MDI application, then you need to call the
ShowDialog
method usingf1
as the parameter.Note that
CenterParent
does not work correctly withShow
since there is no way to set theParent
, so ifShowDialog
is not appropriate, the manual approach is the only viable one.如果您像这样设置子表单的所有者:
然后您可以像这样轻松地将其居中:
If you set the owner of the child form like so:
You can then center it easily like this:
我在我的主窗体中使用此代码,希望它有帮助:
I'm using this code inside my main form, hope it helps:
我发现在一些更复杂的情况下,当表单自动调整大小和动态修改时,手动设置位置是唯一可靠的选择。
然而,我建议使用现有方法,而不是手动计算坐标:
I found setting the location manually is the only reliable option in some more complex cases when form is auto-sized and dynamically modified.
However rather than computing the coordinates manually, I'd suggest using existing method:
我遇到了同样的问题,我最终选择了这个:
用作:
主要优点是它可以完成您的同事期望它做的事情,而不需要在调用表单中进行任何修改。
I had the same problem, I eventually went with this:
Used as:
The main advantage is that it does what your colleagues expect it to do, without requiring any hack in the calling form.
我找到了一个解决方案,它将无模式窗口位置居中到父窗口的位置,并且子窗口仍然可以被父窗口覆盖。
您只需调用
它将 f2 所有者设置为 f1,f2 将显示在 f1 的中心位置。
接下来你设置
一下,f2 是一个单独的窗口,具有正确的启动位置。
I found a solution that will center modeless window position to parent's position, and the child window can be still covered by parent window.
You just have to call
which will set f2 owner to f1, f2 will show over the f1 at it's center position.
Next you set
and there you go, f2 is a separate window, with correct startup position.
我意识到这是一个老问题,但我最近遇到了同样的问题,并且由于我不会进入的原因,我不想使用 form.ShowDialog() 方法,并且我的应用程序不是 MDI 应用程序,因此CenterParent 方法没有任何效果。这就是我解决问题的方法,通过计算我想要居中的表单的坐标并在主表单的 LocationChanged 事件中触发新位置。希望这能帮助其他遇到此问题的人。
在下面的示例中,父窗体称为 MainForm,我想要以 MainForm 为中心的窗体称为 pleaseWaitForm。
如果您有一个可调整大小的父窗体,并且您希望子窗体在主窗体大小调整时也居中,那么理论上您应该能够将此代码放在一个方法中,然后在 LocationChanged 和 SizeChanged 上调用该方法事件。
I realize this is an old question, but I was recently having the same problem and for reasons I won't get in to, I did not want to use the form.ShowDialog() method and my application was not an MDI application, therefore the CenterParent method was not having any effect. This is how I solved the problem, by computing the coordinates for the form that I wanted centered and triggering the new location in the main form's LocationChanged event. Hopefully this will help someone else having this problem.
In the example below, the parent form is called MainForm and the form I want centered in MainForm is called pleaseWaitForm.
If you have a resizable parent form and you wanted your sub form to also be centered whenever the main form is resized, you should, in theory, be able to place this code in a method and then call the method on both the LocationChanged and SizeChanged events.
JYelton 的答案对我有用,但表单仅在第一次调用 Show() 时居中。
如果您想 Hide() 表单,然后在每次调用 Show() 时将其重新集中在父级上,则需要在表单中使用以下内容:
JYelton's answer worked for me, but the form is only centered the first time Show() is called.
If you want to Hide() the form, and then have it re-centered on the parent every time Show() is called you need use the following in your form:
也许这可以帮助某人。
根据经验,虽然它们看起来相似,但它们的行为不同:
这个变体不起作用:
这个变体起作用
Maybe this can help somebody.
From experience, although they look similar, they behave different:
This variant doesn't work:
And this variant works
则使用
如果您第二次调用它, 会引发异常。手动设置位置似乎是唯一可靠的选择:/(CenterParent 不是最近才开始工作的吗?)
Using
throws an exception if you call it a second time. Manually setting the location seems to be the only reliable option :/ (wasn't it fairly recently that CenterParent used to work?)
只需将代码放入表单的构造函数中即可。
just put the code in the constructor of your form.
JYelton 答案的小改动
Small Change to JYelton's answer
我知道,这是一个老问题,但我也遇到了同样的问题,但原因不同。
我打开的表单有一个被重写的 OnLoad 方法:
但没有调用基本实现 因为它必须这样做:
An old question, I know, but I had the same issue but for a different reason.
The Form I was opening had an overridden OnLoad method:
but was not calling the base implementation as it must do:
建立 deerchao 的答案,
在 form.Show() 之后执行此操作,这也适用于多显示器
Building off the answer by deerchao,
Do this after form.Show(), this will work on multi-monitors also