Show a child form in the centre of Parent form in C#
Asked Answered
T

20

92

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?

Tunstall answered 3/6, 2009 at 13:54 Comment(0)
C
151

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.

Cactus answered 3/6, 2009 at 13:57 Comment(4)
You can also set that property of the LoginForm in the designer.Melba
loginForm.StartPosition = FormStartPosition.CenterParent plus loginForm.Show(this); does not center the form.Caryopsis
@Caryopsis 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??Ethiopian
@Ethiopian 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.Caryopsis
P
42

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.

Phyliciaphylis answered 2/3, 2016 at 23:31 Comment(1)
This is the answer if you don't want to use ShowDialog().Burstone
K
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;
    }
}
Kerrikerrie answered 1/8, 2011 at 15:51 Comment(2)
I’m pretty sure that CenterParent also operates relative to Owner, at least with the version of .net I’m using.Loree
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.Magnusson
A
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.

Antisepsis answered 3/6, 2009 at 14:1 Comment(0)
H
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();
Heedless answered 15/2, 2012 at 5:12 Comment(0)
R
7
childform = new Child();
childform.Show(this);

In event childform load

this.CenterToParent();
Reams answered 17/11, 2016 at 7:47 Comment(0)
C
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
Coronograph answered 4/10, 2010 at 13:26 Comment(0)
D
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));
Dynel answered 3/3, 2020 at 12:13 Comment(0)
P
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);
Proportional answered 13/10, 2017 at 20:41 Comment(0)
T
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();
Trolly answered 3/6, 2009 at 14:1 Comment(0)
O
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.

Oldfashioned answered 21/10, 2014 at 14:22 Comment(0)
E
0

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

yourChildFormName x = new yourChildFormName();
x.ShowDialog();
Erle answered 7/10, 2014 at 20:44 Comment(0)
H
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);
}
Hailstorm answered 5/6, 2017 at 17:5 Comment(0)
C
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.

Caladium answered 15/11, 2018 at 6:55 Comment(0)
C
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

Chough answered 10/7, 2020 at 4:30 Comment(0)
N
0

Here is a function that you can use to center a form on another form while ensuring that the target form is fully visible on the screen if the parent form is near the edge. This is for use in cases where you do not want to have a blocking dialog with ShowDialog() or you do not want to put this.CenterToParent() in your target form's load event.

/// <summary>
/// Change the position of the target form to be centered on the parent form while ensuring
/// that the target form is fully visible on the screen that the parent form is on in a
/// multiple monitor scenario or where the parent form is near the screen edge.
/// </summary>
/// <param name="parent">Parent form</param>
/// <param name="target">Target/child form</param>
/// <remarks>Modeled after Form.CenterToParent()</remarks>
/// <example>
/// var frm = new Form1();
//      CenterOnParentForm(this, frm);
//      frm.Show(this);
/// </example>
public void CenterOnParentForm(Form parent, Form target) {
    if (parent == null || target == null) { return; };

    target.StartPosition = FormStartPosition.Manual;

    var targetPoint = new Point();
    var parentScreen = Screen.FromControl(parent);

    if (parentScreen == null) {
        // Something terrible, let's just center on primary screen
        var primaryScreenRect = Screen.PrimaryScreen.WorkingArea;
        targetPoint.X = Math.Max(primaryScreenRect.X, primaryScreenRect.X + (primaryScreenRect.Width - target.Width) / 2);
        targetPoint.Y = Math.Max(primaryScreenRect.Y, primaryScreenRect.Y + (primaryScreenRect.Height - target.Height) / 2);
    }
    else {
        var parentScreenArea = parentScreen.WorkingArea; // Screen minus taskbar
        
        targetPoint.X = parent.Location.X + ((parent.Size.Width - target.Size.Width) / 2);
        targetPoint.Y = parent.Location.Y + ((parent.Size.Height - target.Size.Height) / 2);

        // Adjust target location to not overlap off of or onto another screen
        if (targetPoint.X < parentScreenArea.X) {
            targetPoint.X = parentScreenArea.X;
        }
        else if (targetPoint.X + target.Size.Width > parentScreenArea.X + parentScreenArea.Width) {
            targetPoint.X = parentScreenArea.X + parentScreenArea.Width - target.Size.Width;
        }

        if (targetPoint.Y < parentScreenArea.Y) {
            targetPoint.Y = parentScreenArea.Y;
        }
        else if (targetPoint.Y + target.Size.Height > parentScreenArea.Y + parentScreenArea.Height) {
            targetPoint.Y = parentScreenArea.Y + parentScreenArea.Height - target.Size.Height;
        }
    }

    target.Location = targetPoint;
}
Nonlegal answered 8/11, 2023 at 19:19 Comment(0)
P
-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()
Paleogeography answered 3/6, 2009 at 14:4 Comment(1)
CenterToParent is not a public method. You need to delegate this method as a public method from your control.Pentathlon
S
-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();
Shrinkage answered 15/9, 2015 at 6:16 Comment(0)
K
-2
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);

        CenterToParent();
    }
Katar answered 5/7, 2019 at 17:52 Comment(0)
I
-4

Why not use this?

LoginForm.WindowStartupLocation = Windows.WindowStartupLocation.CenterOwner 

(vb.net)

Ito answered 2/10, 2012 at 17:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.