在C#中以父表单的中心显示子表单

时间:2009-06-03 13:54:50

标签: c# winforms

我创建了一个新表单并从父表单调用如下:

loginForm = new SubLogin();   
loginForm.Show();

我需要在父级的中心显示子表单。所以,在子表单加载中我做了foll:`

Point p = new Point(this.ParentForm.Width / 2 - this.Width / 2, this.ParentForm.Height / 2 - this.Height / 2);
this.Location = p;

但是这会抛出错误,因为父窗体是null。我也尝试设置Parent属性,但没有帮助。对此有任何意见吗?

19 个答案:

答案 0 :(得分:125)

尝试:

loginForm.StartPosition = FormStartPosition.CenterParent;
loginForm.ShowDialog(this);

当然,子窗口将成为父窗口的阻止窗体(对话框),如果不需要,则只需将ShowDialog替换为Show ..

loginForm.Show(this);

您仍然需要指定StartPosition。

答案 1 :(得分:15)

“父母”和“所有者”之间似乎存在混淆。如果您打开一个MDI格式的表单,即嵌入另一个表单内,那么这个周围的表单就是Parent。具有值FormStartPosition.CenterParent的表单属性StartPosition引用此属性。您可以传递给Show方法的参数是Owner,而不是Parent!这就是为什么frm.StartPosition = FormStartPosition.CenterParent无法正常工作的原因。

如果将其StartPosition设置为Manual,则表单中放置的以下代码将使其所有者具有一定的偏移量。小偏移以平铺方式打开表单。如果所有者和拥有的表单具有相同的大小或者您打开多个拥有的表单,则这是一个优势。

protected override void OnShown(EventArgs e)
{
    base.OnShown(e);
    if (Owner != null && StartPosition == FormStartPosition.Manual) {
        int offset = Owner.OwnedForms.Length * 38;  // approx. 10mm
        Point p = new Point(Owner.Left + Owner.Width / 2 - Width / 2 + offset, Owner.Top + Owner.Height / 2 - Height / 2 + offset);
        this.Location = p;
    }
}

答案 2 :(得分:10)

假设您的代码在父表单中运行,那么您可能正在寻找类似的内容:

loginForm = new SubLogin();
loginForm.StartPosition = FormStartPosition.CenterParent
loginForm.Show(this);

对于记录,还有一个Form.CenterToParent()函数,如果你因为某种原因需要在创建后居中它。

答案 3 :(得分:8)

父母的设置对我不起作用,除非我使用form.ShowDialog();

使用form.Show();form.Show(this);时,除非我使用this.CenterToParent();,否则无效。 我只是把它放在表单的 Load 方法中。一切都很好。

设置了父级中心的起始位置,并在使用阻止showdialog时起作用。

答案 4 :(得分:7)

MDIForm表单中启动表单时,您需要使用.CenterScreen而不是.CenterParent

FrmLogin f = new FrmLogin();
f.MdiParent = this;
f.StartPosition = FormStartPosition.CenterScreen;
f.Show();

答案 5 :(得分:4)

你需要这个:

将此替换为this.parent,但您需要在显示该表单之前设置父级。

  Private Sub ÜberToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ÜberToolStripMenuItem.Click

        'About.StartPosition = FormStartPosition.Manual ' !!!!!
        About.Location = New Point(Me.Location.X + Me.Width / 2 - About.Width / 2, Me.Location.Y + Me.Height / 2 - About.Height / 2)
        About.Show()
    End Sub

答案 6 :(得分:3)

它适用于所有情况,将Form1换成主表单。

Popup popup = new Popup();
popup.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
popup.Location = new System.Drawing.Point((Form1.ActiveForm.Location.X + Form1.ActiveForm.Width / 2) - (popup.Width / 2),(Form1.ActiveForm.Location.Y + Form1.ActiveForm.Height / 2) - (popup.Height / 2));
popup.Show(Form1.ActiveForm);

答案 7 :(得分:3)

childform = new Child();
childform.Show(this);

在事件子格式加载

this.CenterToParent();

答案 8 :(得分:2)

在SubLogin表单上,我将公开一个SetLocation方法,以便您可以从父表单设置它:

public class SubLogin : Form
{
   public void SetLocation(Point p)
   {
      this.Location = p;
   }
} 

然后,从您的主要表格:

loginForm = new SubLogin();   
Point p = //do math to get point
loginForm.SetLocation(p);
loginForm.Show();

答案 9 :(得分:2)

当您要使用非阻塞窗口(show()而不是showDialog())时,此方法将无效:

//not work with .Show(this) but only with .ShowDialog(this)
loginForm.StartPosition = FormStartPosition.CenterParent;
loginForm.Show(this);

在这种情况下,可以在显示表单之前使用以下代码来居中子表单:

//this = the parent
frmDownloadPercent frm = new frmDownloadPercent();
frm.Show(this); //this = the parent form
//here the tips
frm.Top = this.Top + ((this.Height / 2) - (frm.Height / 2));
frm.Left = this.Left + ((this.Width / 2) - (frm.Width / 2));

答案 10 :(得分:1)

如果您想计算自己的位置,请先将StartPosition设为FormStartPosition.Manual

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

这是主/父表格,就像Location.X。

StartPosition的默认值为FormStartPosition.CenterParent,因此会在显示后更改孩子的位置。

答案 11 :(得分:0)

如果你必须将childForm置于中心,那么代码将是这样的。此代码位于childForm.cs

this.Show(parent as Form);    // I received the parent object as Object type
this.CenterToParent();

答案 12 :(得分:0)

创建一个Windows窗体,然后为它添加选项:CenterParent然后使用此代码:

yourChildFormName x = new yourChildFormName();
x.ShowDialog();

答案 13 :(得分:0)

您可以在子窗体的构造函数中设置StartPosition,以便窗体的所有新实例都以其父窗口为中心:

public MyForm()
{
    InitializeComponent();

    this.StartPosition = FormStartPosition.CenterParent;
}

当然,您也可以在子窗体的Designer属性中设置StartPosition属性。如果要将子窗体显示为模式对话框,只需在ShowDialog方法的参数中设置窗口所有者:

private void buttonShowMyForm_Click(object sender, EventArgs e)
{
    MyForm form = new MyForm();
    form.ShowDialog(this);
}

答案 14 :(得分:0)

如果从主窗口(父窗体)的新线程中打开了任何窗口窗体(子窗体),则不可能将子窗口保持在主窗口的中心,因此我们需要固定子窗口的位置X和Y坐标手动打开窗口。

在子窗口的属性中,将“ StartPosition”更改为“ Manual”

主窗口中的代码

private void SomeFunction()
{
    Thread m_Thread = new Thread(LoadingUIForm);
    m_Thread.Start();
    OtherParallelFunction();
    m_Thread.Abort();
}

private void LoadingUIForm()
{
    m_LoadingWindow = new LoadingForm(this);
    m_LoadingWindow.ShowDialog();
}

子窗口中的代码,用于通过父当前位置以及大小来定义其自身位置

public LoadingForm(Control m_Parent)
{
   InitializeComponent();
   this.Location = new Point( m_Parent.Location.X+(m_Parent.Size.Width/2)-(this.Size.Width/2),
                              m_Parent.Location.Y+(m_Parent.Size.Height/2)-(this.Size.Height/2)
                            );
}

在此计算父中心的坐标,并通过(this.height / 2)和(this.width / 2)this计算其自身中心,从而将子窗口精确地保持在父窗口的中心。父移动事件也可以进一步使用该功能。

答案 15 :(得分:0)

当您尝试访问父级时,父级可能尚未设置。

试试这个:

loginForm = new SubLogin();
loginForm.Show(this);
loginForm.CenterToParent()

答案 16 :(得分:0)

作为子表单,我认为在显示为对话框之前,它不会在父表单的中间开始。 .......... Form2.ShowDialog();

我正准备制作About Form。 这就是我正在寻找的完美选择。 直到您关闭About_form后,您才能点击/单击About_Form(在我的情况下),无法触摸/单击任何父母的表单 。将其显示为对话框

答案 17 :(得分:-1)

    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);

        CenterToParent();
    }

答案 18 :(得分:-4)

为什么不用这个?

LoginForm.WindowStartupLocation = Windows.WindowStartupLocation.CenterOwner 

(vb.net)