Dans le code suivant, seule la deuxième méthode fonctionne pour moi (.NET 4.0). FormStartPosition.CenterParent
ne centre pas le formulaire enfant sur son parent. Pourquoi?
Source: cette 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);
}
}
En effet, vous ne dites pas à f2
qui est sa Parent
.
S'il s'agit d'une application MDI, alors f2
devrait avoir sa MdiParent
définie sur f1
.
Form f2 = new Form() { Width = 400, Height = 300 };
f2.StartPosition = FormStartPosition.CenterParent;
f2.MdiParent = f1;
f2.Show();
S'il ne s'agit pas d'une application MDI, vous devez appeler la méthode ShowDialog
en utilisant f1
comme paramètre.
Form f2 = new Form() { Width = 400, Height = 300 };
f2.StartPosition = FormStartPosition.CenterParent;
f2.ShowDialog(f1);
Notez que CenterParent
ne fonctionne pas correctement avec Show
car il n’existe aucun moyen de définir Parent
. Par conséquent, si ShowDialog
n’est pas approprié, la méthode manuelle est la seule possible.
Si vous définissez le propriétaire du formulaire enfant comme suit:
Form2 f = new Form2();
f.Show(this);
Vous pouvez ensuite le centrer facilement comme ceci:
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);
}
J'utilise ce code dans mon formulaire principal, j'espère que cela aidera:
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));
}
J'ai constaté que définir manuellement l'emplacement est la seule option fiable dans certains cas plus complexes, lorsque le formulaire est automatiquement dimensionné et modifié dynamiquement.
Cependant, plutôt que de calculer les coordonnées manuellement, je suggérerais d'utiliser la méthode existante:
this.CenterToParent();
J'ai trouvé une solution centrant la position de la fenêtre sans modèle sur la position du parent, la fenêtre enfant pouvant toujours être couverte par la fenêtre parent
f2.Show(f1);
qui définira le propriétaire de f2 sur f1, f2 s'affichera par-dessus le f1 en position centrale.
Ensuite, vous définissez
f2.Owner = null;
et voilà, f2 est une fenêtre séparée, avec la position de démarrage correcte.
J'ai eu le même problème, je suis finalement allé avec ceci:
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);
}
Utilisé comme:
MyForm form = new MyForm();
form.Show(this); // with or without
Le principal avantage est qu'il répond aux attentes de vos collègues, sans qu'il soit nécessaire de modifier le formulaire d'appel.
La réponse de JYelton a fonctionné pour moi, mais le formulaire n'est centré que la première fois que Show () s'appelle . Si vous souhaitez masquer () le formulaire, puis le recentrer sur le parent à chaque fois que Show () est appelé, vous devez utiliser les éléments suivants dans votre formulaire:
public new void Show(IWin32Window owner)
{
base.Show(owner);
if (Owner != null)
Location = new Point(Owner.Location.X + Owner.Width / 2 - Width / 2,
Owner.Location.Y + Owner.Height / 2 - Height / 2);
}
Je me rends compte que c’est une vieille question, mais j’avais récemment le même problème et pour des raisons qui ne m’intéressent pas, je ne souhaitais pas utiliser la méthode form.ShowDialog () et mon application n’était pas un MDI application, la méthode CenterParent n’avait donc aucun effet. Voici comment j'ai résolu le problème en calculant les coordonnées du formulaire que je voulais centrer et en déclenchant le nouvel emplacement dans l'événement LocationChanged du formulaire principal. J'espère que cela aidera quelqu'un d'autre à avoir ce problème.
Dans l'exemple ci-dessous, le formulaire parent s'appelle MainForm et le formulaire que je veux centrer dans MainForm s'appelle pleaseWaitForm.
private void MainForm_LocationChanged(object sender, EventArgs e)
{
Point mainFormCoords = this.Location;
int mainFormWidth = this.Size.Width;
int mainFormHeight = this.Size.Height;
Point mainFormCenter = new Point();
mainFormCenter.X = mainFormCoords.X + (mainFormWidth / 2);
mainFormCenter.Y = mainFormCoords.Y + (mainFormHeight / 2);
Point waitFormLocation = new Point();
waitFormLocation.X = mainFormCenter.X - (pleaseWaitForm.Width / 2);
waitFormLocation.Y = mainFormCenter.Y - (pleaseWaitForm.Height / 2);
pleaseWaitForm.StartPosition = FormStartPosition.Manual;
pleaseWaitForm.Location = waitFormLocation;
}
Si vous avez un formulaire parent redimensionnable et que vous souhaitez que votre sous-formulaire soit également centré chaque fois que le formulaire principal est redimensionné, vous devriez, en théorie, pouvoir placer ce code dans une méthode, puis appeler la méthode à la fois sur LocationChanged et SizeChanged. événements.
En utilisant
form.Show(this);
lève une exception si vous l'appelez une seconde fois. Définir manuellement l’emplacement semble être la seule option fiable:/(n’était-ce pas assez récemment que CenterParent fonctionnait auparavant?)
Peut-être que cela peut aider quelqu'un.
Form frmMessage = new Form();
Par expérience, même s’ils se ressemblent, ils se comportent différemment:
Cette variante ne fonctionne pas:
if (frmMessage.Parent != null)
frmMessage.CenterToParent();
else
frmMessage.CenterToScreen();
Et cette variante fonctionne
if (frmMessage.Parent != null)
frmMessage.StartPosition = FormStartPosition.CenterParent;
else
frmMessage.StartPosition = FormStartPosition.CenterScreen;
Une vieille question, je sais, mais j'avais le même problème mais pour une raison différente.
Le formulaire que j'ouvrais avait une méthode OnLoad remplacée:
protected override void OnLoad(EventArgs e)
{
//... etc.
}
mais n'appelait pas l'implémentation de base comme il se doit :
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//... etc.
}
Lorsque vous substituez OnLoad (EventArgs) dans une classe dérivée, veillez à appeler la méthode OnLoad (EventArgs) de la classe de base afin que les délégués enregistrés reçoivent l'événement.
Petit changement à la réponse de JYelton
Form2_Load(object sender, EventArgs e)
{
if (Owner != null && Parent == null && StartPosition == FormStartPosition.CenterParent)
Location = new Point(Owner.Location.X + Owner.Width / 2 - Width / 2,
Owner.Location.Y + Owner.Height / 2 - Height / 2);
}