2010-12-13 14 views
8

Básicamente tengo dos problemas con C# .NET MDI. Puede descargar la solución VS2010 que reproduce los errores here.C# .NET MDI se equivoca al ocultar por programación y muestra de nuevo un formulario maximizado y cuando se maximiza, el icono de formulario secundario no se puede cambiar

1) Cuando se oculta de forma programada y se vuelve a mostrar un formulario secundario maximizado, no se maximiza correctamente de nuevo y no se maximiza ni se encuentra en estado normal.

childForm = new Form(); 
childForm.Text = "Child Form"; 
childForm.MdiParent = this; 

... 

private void showButton_Click(object sender, EventArgs e) 
{ 
    childForm.Visible = true; 
} 

... 

private void hideButton_Click(object sender, EventArgs e) 
{ 
    childForm.Visible = false; 
} 

Cuando se maximiza formulario secundario, entonces programicaly ocultos y muestra una vez más, se convierte en algo como esto (por favor, observe la barra de menús - Aparece el cuadro de control del formulario secundario, pero formulario secundario no está maximizada):

alt text

En esta etapa, no se puede mover la forma del niño. Sin embargo, encontré una solución para eso, simplemente mostrando y ocultando una forma de niño falso, lo que obliga a que la forma real del niño se maximice adecuadamente. Pero esto hace que el área MDI parpadee. Intentó Invalidar, Actualizar, Actualizar métodos, pero no ayuda. Tal vez haya otras soluciones para superar este error y no para hacer que el área MDI parpadee con la forma de un hijo ficticio.

private void workaround1Button_Click(object sender, EventArgs e) 
{ 
    dummyForm.Visible = true; 
    dummyForm.Visible = false; 
} 

2) Cuando se maximiza el formulario secundario, el icono del formulario secundario se muestra en la barra de menú. Sin embargo, si tiene que cambiar el ícono mientras se maximiza el formulario secundario, el ícono en la barra de menú no se actualiza (vea la imagen de arriba). Encontré una solución para eso también, que básicamente oculta y muestra la barra de menús. Icon se actualiza, pero hace que todo lo que está debajo de la barra de menú parpadee. Intentó Invalidar, Actualizar, Actualizar métodos, pero no ayuda. ¿Hay alguna otra forma de hacer que la barra de menú actualice el icono del formulario secundario?

private void workaround2Button_Click(object sender, EventArgs e) 
{ 
    menuStrip.Visible = false; 
    menuStrip.Visible = true; 
} 

También he notado que cuando la forma de los padres está en modo de estado de ventana normal (no maximizado) y se cambia la anchura o la altura de la forma por 1 píxel, la forma niño se maximiza como debe ser y El ícono del formulario hijo en la barra de menú se actualiza correctamente y no necesita otra solución que describí anteriormente. Si cambio el tamaño del formulario de forma programática, los parpadeos de forma en 1 píxel y no puedo hacer eso, cuando se maximiza el formulario principal. ¿Hay alguna manera de invocar la funcionalidad de volver a pintar/actualizar que se llama cuando se cambia el tamaño de un formulario y que hace que la forma infantil se maximice correctamente y se actualice el icono en la barra de menú?

Respuesta

1

encontrado una manera de cómo llegar en torno a esos errores.

En primer lugar, debe suspender la pintura de un formulario y sus hijos. Encontré un hilo muy útil, here, que describe cómo hacerlo.

Después de suspender la pintura, debe llamar al método UpdateBounds del control y aumentar el ancho o la altura de ClientRectangle en uno y luego disminuirlo al mismo valor que antes. Esto invoca la funcionalidad de diseño que hace que todo se actualice/vuelva a pintar. El último paso es habilitar la pintura. No es una solución muy agradable, supongo, pero funciona.

StopDrawing(); 
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height + 1); 
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height - 1); 
StartDrawing(); 

me parece suspender pintura muy útil no sólo para trabajar en torno a esos dos insectos, sino también, en general, a hacer el trabajo de interfaz gráfica de usuario más fluida. Supongo que esto puede ayudar a eliminar cualquier tipo de parpadeo. Sin embargo, esta solución requiere P/Invocaciones, que deben evitarse en general.

1

¿Ha cansado de usar Ocultar/Mostrar en lugar de establecerlo como verdadero/falso?

Probar:

private void showButton_Click(object sender, EventArgs e) 
{ 
    childForm.Show(); 
} 

private void hideButton_Click(object sender, EventArgs e) 
{ 
    childForm.Hide(); 
} 
+0

Sí, lo han intentado, pero nada cambia. Creo que childForm.Visible = true/false llama a esos métodos. – Povilas

+1

En realidad, debería ser al revés. Hide/Show debería establecerse como visible a falso/verdadero. –

1

Hay un error en la implementación de la clase MdiControlStrip interna, el control que muestra el icono y los mín/máx/restauración glifos de la ventana padre. No lo he caracterizado todavía, el código no es tan fácil. Un efecto secundario clásico del error es que los glifos se doblan, encontraste algunos otros efectos secundarios. La solución es simple, demora la creación de las ventanas secundarias hasta que se complete el constructor. De esta manera:

public MainForm() 
    { 
     InitializeComponent(); 
    } 
    protected override void OnLoad(EventArgs e) { 
     childForm = new Form(); 
     childForm.Text = "Child Form"; 
     childForm.MdiParent = this; 

     dummyForm = new Form(); 
     dummyForm.MdiParent = this; 
     dummyForm.WindowState = FormWindowState.Maximized; 
     base.OnLoad(e); 
    } 
+0

Ah, sí, usaste el evento Load. Mueva la base.OnLoad() hacia la parte inferior. Funciona en mi máquina ™. –

+0

Ha intentado solucionar el problema anulando el método OnLoad, pero el mismo comportamiento con errores persiste. Nada cambia. Y los formularios secundarios deben crearse dinámicamente, por lo que esta no sería realmente una solución para mí. – Povilas

1

¿Qué tal esta solución?

ACTUALIZACIÓN

Me acabo de dar la idea de lo que podría hacer. Una mejor solución usando la misma idea que la anterior sería una nueva forma base que guarda el estado de Windows. Vea abajo. Derivar sus formas de FixedForm en lugar del Formulario:

public partial class FixedForm : Form 
{ 
    private FormWindowState lastWindowState; 

    public FixedForm() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnVisibleChanged(EventArgs e) 
    { 
     base.OnVisibleChanged(e); 

     if (Visible) 
     { 
      WindowState = lastWindowState; 
     } 
     else 
     { 
      lastWindowState = WindowState; 
      WindowState = FormWindowState.Normal; 
     } 
    } 
} 
+0

Definitivamente esta es una de las posibilidades de cómo superar el error, pero hace que maximizar la animación de la forma infantil aparezca una y otra vez, es un poco molesto. Mi solución en eso es más rápido. – Povilas

+0

Revise mi actualización para encontrar una solución sin parpadear – Scoregraphic

+0

, puede enviar un mensaje 'WM_SIZE' al manejador de la ventana primaria si esto resuelve el problema. – Scoregraphic

0

Por qué no sólo restablecer manualmente icono solicitan en los puntos MenuStrip, después de la creación de la ventana:

menuStripMain.Items[0].Image = null; 
Cuestiones relacionadas