studio sobre reales proyectos programacion libro introducción incluye herramientas fundamentos fuente español código con avanzado aplicaciones c# winforms .net-3.5 mdi mdichild

c# - reales - Los controles en forma de contenedor vienen sobre la forma del niño?



manual android studio avanzado (8)

En forma de contenedor, tengo un menú y botones para abrir los formularios.

Aquí estoy enfrentando un problema cuando abro cualquier formulario, estos extremos y etiquetas vienen de forma recién abierta.

¿Por favor guíame cómo puedo manejar este problema? Quiero abrir un nuevo formulario y mantener los controles del formulario de este contenedor en un segundo plano.


@ Hans Passant tiene la respuesta correcta, pero también podría resolver su problema al no usar formularios MDI en absoluto. Algunas opciones:

  • Use formularios separados: tenga un formulario de menú, normalmente grande / maximizado, y lance formularios secundarios delante de él configurando su propiedad Parent en el formulario del menú, o
  • Use una sola forma, pero con una biblioteca de acoplamiento (he usado DockPanel Suite en el pasado). Esto es esencialmente una reimplementación de formularios MDI, con características adicionales. Esto es un poco difícil de ejecutar, pero puede permitirle construir algunas interfaces de usuario agradables.

Sin embargo, ambos requerirían cambios significativos en su código de UI.


Creo que veo lo que hiciste. Está utilizando MDI y coloca las etiquetas de menú y los botones en el formulario principal de MDI. Hiciste algo con la ventana del cliente MDI, normalmente es de color gris oscuro. Tal vez descubrió cómo cambiar su BackColor o cambió el color del sistema de Windows. Sí, tu pantalla captó el resultado. El problema es que los formularios de cliente MDI están emparentados con la ventana del cliente MDI. Lo que los hace aparecer detrás de los controles que colocas en el formulario principal.

No hay una solución para esto, tendrá que cambiar su UI. Para mantener MDI, coloque un Panel en el formulario principal y establezca su propiedad Dock a la izquierda. Mueva los controles del menú sobre eso. La ventana del cliente MDI ahora se reducirá, ocupando el resto del formulario principal. Y las formas de los niños se limitarán a esa área. Lo peor es que tendrá que reorganizar el menú para que se ajuste al espacio mucho más pequeño disponible en el panel.


El truco principal aquí es tratar formas de niños como Controles. Creará una forma secundaria como cualquier otro control. Cuando utiliza este método, debe configurar su TopLevel en falso; de lo contrario, no funcionará.

Las siguientes líneas de código se utilizan para crear un formulario secundario:

Form childForm = new Form(); //initialize a child form childForm.TopLevel = false; //set it''s TopLevel to false Controls.Add(childForm); //and add it to the parent Form childForm.Show(); //finally display it childForm.BringToFront(); //use this it there are Controls over your form.

más detalles aquí


Llame a BringToFront () en cada formulario secundario después de mostrarlos. Alternativamente, enganche al método OnLoad de cada niño:

childForm.OnLoad += (s, e) => (s as Form).BringToFront();


Parece que esa forma es un hermano de esos otros controles secundarios. ¿Tienes que abrirlo como un niño de esa ventana? ¿No puede ser como un cuadro de diálogo no modal y no como una ventana secundaria de ese formulario principal?

Si tiene que estar dentro de esa forma principal y un hermano de esos controles, entonces tendrá que establecer el orden Z de la misma. No hay ninguna propiedad para eso, por lo que tendrá que mirar hacia la llamada API de Win32, SetWindowPos :

[DllImport("user32.dll", EntryPoint = "SetWindowPos")] public static extern bool SetWindowPos( int hWnd, // window handle int hWndInsertAfter, // placement-order handle int X, // horizontal position int Y, // vertical position int cx, // width int cy, // height uint uFlags); // window positioning flags const uint SWP_NOSIZE = 0x1; const uint SWP_NOMOVE = 0x2; const uint SWP_SHOWWINDOW = 0x40; const uint SWP_NOACTIVATE = 0x10;

Y llámalo algo como esto:

SetWindowPos((int)form.Handle, // that form (int)insertAfter.Handle, // some other control 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);


Si se trata de una aplicación MDI y usted coloca controles en la ventana principal, se mostrarán encima de cualquier ventana secundaria creada. También debe tener su menú en una ventana secundaria, no en el formulario principal.

Mira este artículo y esto .

Especialmente esto:

El formulario principal no puede contener ningún control. >

Editar: se agregó información adicional


También tengo el mismo problema. Obtuve una solución alternativa como se describe a continuación:

  1. Inserte un control de temporizador
  2. He agregado los controles en un contenedor de panel
  3. E hizo lo siguiente

    private void timer1_Tick(object sender, EventArgs e) { if ((int)MdiChildren.GetLength(0) > 0) { panel1.Visible = false; } else { panel1.Visible = true; } }


Tuve este problema y lo resolvió de esta manera:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { [DllImport("user32.dll", SetLastError = true)] static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); Form2 F2; public Form1() { InitializeComponent(); F2 = new Form2(); } private void Form1_Load(object sender, EventArgs e) { Panel P1 = new Panel(); P1.Location = new Point(0, 0); P1.Height = this.Height; P1.Width = this.Width; P1.BackColor = Color.Transparent; this.Controls.Add(P1); SetParent(F2.Handle, P1.Handle); F2.Owner = this; F2.Show(); } }