Voici une réponse qui implique un peu de "déblayage" en utilisant un panneau et une stratégie pour masquer et afficher l'objet MdiClient de la forme principale de l'application MDI.
Lorsque toutes les fenêtres enfants MDI sont fermées, le Panel remplira la zone du client MDI et gérera les événements de la souris. Si vous définissez la propriété BackColor du panneau pour qu'elle corresponde à la couleur d'arrière-plan de la zone client MDI par défaut (voir ci-dessous), vous pouvez effectuer une transition visuelle "transparente" ... bien que: vous souhaitiez que la couleur varie une stratégie délibérée pour informer l'utilisateur d'un double-clic, ou de tout autre événement de souris que vous voulez gérer, est disponible.
Alors que vous pouvez obtenir ce fonctionnement, comme indiqué dans cet exemple, je vous encourage à réfléchir si cette fonctionnalité est "vraiment la peine".
Je n'ai pas évalué la suggestion raisonnable de Gareth S. ci-dessus pour résoudre cela en utilisant la propriété 'IsMdiContainer' sur le formulaire MDI principal pour la simple raison que je crains que cela implique de recréer des configurations de fenêtrage complexes, et l'effet secondaire de définir 'IsMdiContainer sur false sur un formulaire où la propriété' IsMdiContainer est 'true est de supprimer le contrôle MdiClient de la collection de contrôle du formulaire: Je suppose qu'il y aurait des effets secondaires délicats à cela, mais je pourrais être complètement faux. Je suis plus à l'aise avec une stratégie qui cache et affiche l'objet MdiClient plutôt que celui qui le supprime comme un effet secondaire de la définition d'une propriété, et qui nécessiterait alors que vous l'ajoutiez à la collection de contrôles de le formulaire principal MDI pour l'utiliser à nouveau. Vous pourriez faire un autre choix. Je ne vais pas entrer dans la façon dont l'objet MdiClient est géré en interne, mais "couper à la chasse" et vous montrer comment contourner son manque de gestion de certains événements de la souris.
Hypothèses:
- Vous avez défini un formulaire « secondaire » nommé Form2 qui sera utilisé pour toutes les fenêtres enfants du principal formulaire MDI.
code:
Ajouter un panneau à votre principal formulaire MDI: définissez son DockStyle à « remplir; définissez BackColor pour utiliser la couleur AppWorkspace du système pour un arrière-plan correspondant aux paramètres de préférences de couleur de l'utilisateur de l'utilisateur (c'est ce que le BackColor par défaut de MdiClient utilise). Écrivez des gestionnaires d'événements dans ce panneau pour 'DoubleClick' ou 'MouseDoubleClick', selon vos préférences.
Dans votre formulaire MDI principal: déclarez une variable étendue de formulaire pour contenir une référence à l'objet MdiClient.
private MdiClient theMdiClient;
Supposons que vous avez également déclaré un groupe de vos fenêtres enfants au niveau du champ de formulaire:
Form2 f2 = new Form2();
Form2 f3 = new Form2();
Form2 f4 = new Form2();
Form2 f5 = new Form2();
principal MDI événement Load: Nous devons obtenir une référence à l'objet MdiClient: si vous savez que vous avez un seul contrôle sur le formulaire (le panneau), vous pouvez être sûr que MainMdiForm.Controls [1] contiendra l'objet MdiClient lors de l'événement Form Load, mais il est préférable de répéter:
Note: nous expliquons le c tout ce qui définit la référence au formulaire MDI principal dans chaque fenêtre enfant (theMdiParent) dans la section 5 ci-dessous
private void Form1_Load(object sender, EventArgs e)
{
// find the MdiClient control and set a reference
foreach (Control theControl in this.Controls)
{
MdiClient testMdiClient = theControl as MdiClient;
if (testMdiClient != null)
{
theMdiClient = testMdiClient;
break;
}
}
// hide the panel
panel1.Hide();
// set child windows MdiParent to Main MDI Form
// set the child windows reference to this Form
// show the child windows
f2.MdiParent = this;
// explained in section #5 below
f2.theMDIParent = this;
f2.Show();
f3.MdiParent = this;
f3.theMDIParent = this;
f3.Show();
f4.MdiParent = this;
f4.theMDIParent = this;
f4.Show();
f5.MdiParent = this;
f5.theMDIParent = this;
f5.Show();
// set the initialization flag for future use
isInitializing = false;
}
Maintenant, l'aspect plus intéressant de ce problème: comment pouvons-nous reétrenner le Groupe lorsqu'aucune les fenêtres enfants sont visibles dans le formulaire MDI principal. Nous allons d'abord définir une méthode publique dans le formulaire principal MDI: nous pouvons alors supposer que si cette méthode est appelée par un gestionnaire d'événements FormClosed dans chaque fenêtre enfant: si la propriété MdiChildren.Length du formulaire MDI principal est exactement # 1 : la dernière fenêtre enfant visible restante vient d'être fermé: Notez que nous retirons alors l'objet MdiClient de la collection de contrôles du principal formulaire MDI:
public void MDIChildClosed()
{
if (this.MdiChildren.Length == 1)
{
this.Controls.Remove(theMdiClient);
panel1.Visible = true;
}
}
nous créons une propriété publique dans Form2 (toutes les fenêtres de l'enfant étant cas de Form2) pour maintenir la référence au formulaire principal MDI, qui est leur MdiParent:
public Form1 theMDIParent { get; set; }
Ensuite, nous gérer l'événement FormClosed pour la fenêtre enfant (Form2) en utilisant la référence au parent Mdi (formule 1) pour appeler sa méthode « MdiChildClosed() public:
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
theMDIParent.MDIChildClosed();
}
Et dans la méthode MdiChildClosed() du formulaire principal MDI (Form1): tel que discuté, nous enlevons l'objet MdiClient de la collection de contrôle du principal formulaire MDI, et de rendre le Groupe, qui gère les événements de la souris, à nouveau visible:
public void MDIChildClosed()
{
if (this.MdiChildren.Length == 1)
{
this.Controls.Remove(theMdiClient);
panel1.Visible = true;
}
}
maintenant, espérons-le, vous vous demandez: comment ramener l'objet MdiClient lorsque l'utilisateur final (via le bouton, le menu, etc.) fait de nouveaux Mdi Child Windows après que toutes les fenêtres enfants MDI ont été fermées et le panneau est à nouveau affiché. Cependant, vous déclenchez la création de nouvelles fenêtres enfant, vous allez faire quelque chose comme cela dans le formulaire principal MDI (Form1):
// hide the panel
panel1.Hide();
// add the MdiClient back
this.Controls.Add(theMdiClient);
// example of creating a new child Form
Form2 f6 = new Form2();
f6.MdiParent = this;
f6.theMDIParent = this;
f6.Show();
Résumé: beaucoup de travail pour, à mon humble avis, une relativement faible payer. Évidemment, vous pourriez refactoriser ce code de plusieurs façons, et faire les choses beaucoup plus élégamment. Personnellement, je pense que les applications de type MDI sont depuis longtemps "démodées".
La seule possible « étincelle » qui vole de cette exploration, pour moi, est l'idée que vous pouvez mettre toutes sortes de contrôles de configuration sur votre panneau (tel qu'il est utilisé ici), ont peut-être une option pour cacher toutes les fenêtres enfant MDI et affichez le Panel, plutôt que d'attendre que toutes les fenêtres enfants MDI soient fermées.
'MouseDown' dans la zone cliente peut être manipulé dans le code sans sous-classement, pas de substitutions protégées, pas de WndProc, et aucun paramètre IsMDIContainer à 'false: quand aucune fenêtre enfant n'est montrée; ou, lorsque les fenêtres enfants sont montrées; ou, dans tous les cas. Voulez-code: demander. Une fois que vous manipulez le MouseDown, je suppose que vous pourriez "feindre" détecter un double-clic avec un Timer même si cela pourrait ne pas être élégant. – BillW