91

I create a new form and call from the parent form as follows:

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

I need to display the child form at the centre of the parent. So,in the child form load I do the foll:`

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

But this is throwing error as parent form is null. I tried setting the Parent property as well, but didn't help. Any inputs on this?

Kirtan
  • 21,295
  • 6
  • 46
  • 61

19 Answers19

148

Try:

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

Of course the child form will now be a blocking form (dialog) of the parent window, if that isn't desired then just replace ShowDialog with Show..

loginForm.Show(this);

You will still need to specify the StartPosition though.

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
Quintin Robinson
  • 81,193
  • 14
  • 123
  • 132
  • 18
    You can also set that property of the LoginForm in the designer. – Tim Hoolihan Jun 03 '09 at 13:58
  • 66
    loginForm.StartPosition = FormStartPosition.CenterParent plus loginForm.Show(this); does not center the form. – Pedro77 Jan 31 '14 at 21:11
  • @Pedro77 I have a similar situation except I have done show dialog from a different thread so it won't let me pass "this" to showDialog. any suggestion here?? – Anil Jun 25 '18 at 09:27
  • 1
    @Anil I think you should not create UI itens from a different thread. You should use invoke begininvoke to that task. Take a look at those commands. – Pedro77 Jun 25 '18 at 17:35
41

The setting of parent does not work for me unless I use form.ShowDialog();.

When using form.Show(); or form.Show(this); nothing worked until I used, this.CenterToParent();. I just put that in the Load method of the form. All is good.

Start position to the center of parent was set and does work when using the blocking showdialog.

Wiccio
  • 311
  • 4
  • 14
Highflier
  • 421
  • 4
  • 2
21

There seems to be a confusion between "Parent" and "Owner". If you open a form as MDI-form, i.e. imbedded inside another form, then this surrounding form is the Parent. The form property StartPosition with the value FormStartPosition.CenterParent refers to this one. The parameter you may pass to the Show method is the Owner, not the Parent! This is why frm.StartPosition = FormStartPosition.CenterParent does not work as you may expect.

The following code placed in a form will center it with respect to its owner with some offset, if its StartPosition is set to Manual. The small offset opens the forms in a tiled manner. This is an advantage if the owner and the owned form have the same size or if you open several owned forms.

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;
    }
}
  • 1
    I’m pretty sure that `CenterParent` also operates relative to `Owner`, at least with the version of .net I’m using. – binki May 07 '15 at 18:20
  • That is the only solution that works for me. However, I don't know why but when I call the Show method, the OnShown is not called even if it's marked with the override keyword. My workaround was to create a new method Display that call the Show and do the location trick that you provided. – Samuel Feb 16 '21 at 20:03
15

Assuming your code is running inside your parent form, then something like this is probably what you're looking for:

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

For the record, there's also a Form.CenterToParent() function, if you need to center it after creation for whatever reason too.

Matthew Scharley
  • 127,823
  • 52
  • 194
  • 222
9

When launching a form inside an MDIForm form you will need to use .CenterScreen instead of .CenterParent.

FrmLogin f = new FrmLogin();
f.MdiParent = this;
f.StartPosition = FormStartPosition.CenterScreen;
f.Show();
Dmitrii Lobanov
  • 4,897
  • 1
  • 33
  • 50
timothy
  • 568
  • 8
  • 9
7
childform = new Child();
childform.Show(this);

In event childform load

this.CenterToParent();
4

You need this:

Replace Me with this.parent, but you need to set parent before you show that form.

  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
Stefan Steiger
  • 78,642
  • 66
  • 377
  • 442
4

When you want to use a non-blocking window (show() instead of showDialog()), this not work:

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

In this case, you can use this code to center child form before display the form:

//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));
Digital3D
  • 161
  • 8
3

It works in all cases, swap Form1 for your main form.

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);
2

If you want to calculate your own location, then first set StartPosition to 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);

Where this is the main/parent form, just like Location.X.

Default value for StartPosition is FormStartPosition.CenterParent and therefore it changes the child's location after showing.

slavoo
  • 5,798
  • 64
  • 37
  • 39
Lex van Buiten
  • 138
  • 1
  • 8
2

On the SubLogin Form I would expose a SetLocation method so that you can set it from your parent form:

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

Then, from your main form:

loginForm = new SubLogin();   
Point p = //do math to get point
loginForm.SetLocation(p);
loginForm.Show();
BFree
  • 102,548
  • 21
  • 159
  • 201
0

Make a Windows Form , then put option for it : CenterParent then use this Code :

yourChildFormName x = new yourChildFormName();
x.ShowDialog();
lxg
  • 12,375
  • 12
  • 51
  • 73
0

You can set the StartPosition in the constructor of the child form so that all new instances of the form get centered to it's parent:

public MyForm()
{
    InitializeComponent();

    this.StartPosition = FormStartPosition.CenterParent;
}

Of course, you could also set the StartPosition property in the Designer properties for your child form. When you want to display the child form as a modal dialog, just set the window owner in the parameter for the ShowDialog method:

private void buttonShowMyForm_Click(object sender, EventArgs e)
{
    MyForm form = new MyForm();
    form.ShowDialog(this);
}
iCode
  • 1,254
  • 1
  • 13
  • 16
0

If any windows form(child form) is been opened from a new thread of Main window(parent form) then its not possible to hold the sub window to the center of main window hence we need to fix the position of the sub window manually by means of X and Y co-ordinates.

In the properties of Subwindow change the "StartPosition" to be "Manual"

code in main window

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();
}

code in subwindow for defining its own position by means of parent current position as well as size

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)
                            );
}

Here the co-ordinates of center of parent is calculated as well as the subwindow is kept exactly at the center of the parent by calculating its own center by (this.height/2) and (this.width/2) this function can be further taken for parent relocated events also.

Garuda prasad K
  • 332
  • 3
  • 8
0

As a sub form i think it's not gonna Start in the middle of the parent form until you Show it as a Dialog. .......... Form2.ShowDialog();

i was about to make About Form. and this is perfect that's i am searching for. and untill you close the About_form you cant Touch/click anythings of parents Form once you Click for About_Form (in my case) .Coz its Showing as Dialog

Hassan Uddin
  • 417
  • 5
  • 10
-1

If you have to center your childForm, from childForm then the code will be something like this. This code is in the childForm.cs

this.Show(parent as Form);    // I received the parent object as Object type
this.CenterToParent();
Yousuf Azad
  • 414
  • 1
  • 7
  • 17
-1

The parent probably isn't yet set when you are trying to access it.

Try this:

loginForm = new SubLogin();
loginForm.Show(this);
loginForm.CenterToParent()
jean
  • 1,027
  • 1
  • 8
  • 15
  • 3
    CenterToParent is not a public method. You need to delegate this method as a public method from your control. – Jarek Jul 28 '09 at 11:30
-2
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);

        CenterToParent();
    }
ChRoNoN
  • 860
  • 8
  • 18
-4

Why not use this?

LoginForm.WindowStartupLocation = Windows.WindowStartupLocation.CenterOwner 

(vb.net)

andrewsi
  • 10,807
  • 132
  • 35
  • 51