FormStartPosition.CenterParent不起作用

kol*_*kol 32 c# forms parent-child winforms centering

在下面的代码中,只有第二种方法适用于我(.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); 
  }
}
Run Code Online (Sandbox Code Playgroud)

JYe*_*ton 35

如果您设置子表单的所有者,如下所示:

Form2 f = new Form2();
f.Show(this);
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样轻松地居中:

Form2_Load(object sender, EventArgs e)
{
    if (Owner != null)
        Location = new Point(Owner.Location.X + Owner.Width / 2 - Width / 2,
            Owner.Location.Y + Owner.Height / 2 - Height / 2);
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该是IMO接受的答案 (3认同)
  • 您可以使用 [CenterToParent()](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.form.centertoparent) 来代替手动计算。 (2认同)

com*_*ech 34

这是因为你不f2知道它Parent是谁.

如果这是一个MDI应用程序,那么f2应将其MdiParent设置为f1.

Form f2 = new Form() { Width = 400, Height = 300 };
f2.StartPosition = FormStartPosition.CenterParent;
f2.MdiParent = f1;
f2.Show();
Run Code Online (Sandbox Code Playgroud)

如果这不是MDI应用程序,则需要ShowDialog使用方法f1作为参数调用.

Form f2 = new Form() { Width = 400, Height = 300 };
f2.StartPosition = FormStartPosition.CenterParent;
f2.ShowDialog(f1);
Run Code Online (Sandbox Code Playgroud)

请注意,由于无法设置,因此CenterParent无法正常工作,因此如果不合适,手动方法是唯一可行的方法.ShowParentShowDialog

  • @kol:抱歉,有时人们发布伪代码或其应用程序的更改版本,这就是我提供MDI和非MDI替代品的原因. (2认同)

dee*_*hao 9

我在我的主窗体中使用此代码,希望它有所帮助:

var form = new MyForm();
form.Show();
if (form.StartPosition == FormStartPosition.CenterParent)
{
    var x = Location.X + (Width - form.Width) / 2;
    var y = Location.Y + (Height - form.Height) / 2;
    form.Location = new Point(Math.Max(x, 0), Math.Max(y, 0));
}
Run Code Online (Sandbox Code Playgroud)

  • 最后,唯一的解决方案适用于VS2010上的win形式的C#. (2认同)

she*_*rpa 5

我发现在某些更复杂的情况下,当表单自动调整大小并动态修改时,手动设置位置是唯一可靠的选项。

但是,建议不要使用现有的方法来手动计算坐标:

this.CenterToParent();
Run Code Online (Sandbox Code Playgroud)

  • MSDN:“不要直接从代码中调用CenterToParent方法。相反,请将StartPosition属性设置为CenterParent。” http://msdn.microsoft.com/zh-CN/library/system.windows.forms.form.centertoparent.aspx (2认同)
  • @kol好点。如果设置StartPosition就足够了,那么请确保这是正确的方法。但是在某些情况下则不会(例如,大小会动态更改)。我相信,这是正确的手动方法。 (2认同)

pri*_*imo 5

我遇到了同样的问题,我最终选择了这个:

protected override void OnActivated(EventArgs e) {
    if(this.Modal == false && this.StartPosition == FormStartPosition.CenterParent) {
        if(!(this.Owner is Form)) {
            // Center to the last form opened before this one
            int numforms = Application.OpenForms.Count;
            this.Owner = Application.OpenForms[numforms - 2];
        }
        this.CenterToParent();
        Application.DoEvents();
    }
    base.OnActivated(e);
}
Run Code Online (Sandbox Code Playgroud)

用作:

MyForm form = new MyForm();
form.Show(this); // with or without
Run Code Online (Sandbox Code Playgroud)

主要优点是它可以完成您的同事期望它做的事情,而不需要在调用表单中进行任何修改。