visual tag shown propiedades formulario form eventos .net winforms events .net-2.0

.net - tag - Cargar vs eventos mostrados en Windows Forms



shown c# (6)

Con suerte me falta algo obvio, pero estoy tratando de entender las diferencias entre los eventos Cargar y Mostrar en Windows Forms .

Tradicionalmente, solo he usado Load (o, de hecho, OnLoad, ya que creo que es más claro anular un método que confiar en el diseñador para conectar un evento consigo mismo), ya que está disponible en todas las versiones de .NET. Con .NET 2.0, se presentó el evento Mostrado.

Ahora, si observa las descripciones de estos en la documentación de MSDN ("Cargar: aparece antes de que se muestre un formulario por primera vez"), "Se muestra: se produce cada vez que se muestra el formulario por primera vez"), suena como el evento Cargar debería ocurrir, entonces la forma debería hacerse visible, entonces el evento Mostrado debería ocurrir; la combinación de los dos le permite realizar algunas tareas tanto antes como después de que el formulario sea visible. Tiene sentido, ¿verdad?

Sin embargo, la experimentación ha demostrado que el evento Mostrado invariablemente se produce antes del evento Load, cada vez que lo intento (y ambos ocurren antes de que el formulario sea visible). Y, sin embargo, cuando busco en Google cada vez que descubro una página que habla sobre el orden en el que se activan estos eventos, siempre enumeran primero el evento Load que se activa.

¿Me estoy volviendo loco o me he perdido algo? (Y si ocurren aproximadamente al mismo tiempo, ¿por qué se agregó el evento Mostrado en primer lugar?)

(Mi solución actual para hacer algo antes y después de mostrar el formulario es utilizar OnLoad para las cosas "antes de mostrar" y comenzar un temporizador de una sola toma de corta duración para las cosas "después de mostrar". Lo cual funciona bien y de manera confiable, pero es un poco feo y esperaba que hubiera una solución más limpia. Pero parece que el evento Mostrado no es así).


Acabo de verificar y cargar incendios antes de que se muestre como debería.

Obviamente hay algo mal en su enfoque.


Aquí está la secuencia del evento que tracé. Que esto ayude a otros a decidir cómo les gustaría llamar o configurar su manejo personalizado de eventos

Eventos rastreados

Formulario - Se modificó el tamaño del cliente: 8/14/2010 10:40:28 AM
Formulario - Control agregado - button1: 8/14/2010 10:40:29 AM
Formulario - Constructor: 8/14/2010 10:40:29 AM
Forma - Manija Creado: 8/14/2010 10:40:29 AM
Formulario - Invalidado: 8/14/2010 10:40:29 AM
Formulario - Evento de carga de formulario: 8/14/2010 10:40:29 AM
Forma - Cargado: 8/14/2010 10:40:29 AM
Formulario - Crear control: 8/14/2010 10:40:29 AM
Formulario - Activado: 8/14/2010 10:40:29 AM
Forma - Se muestra: 8/14/2010 10:40:29 AM
Formulario - OnPaint: 8/14/2010 10:40:29 AM
Formulario - Invalidado: 8/14/2010 10:40:29 AM
Formulario - OnPaint: 8/14/2010 10:40:29 AM


Evite usar MessageBox.Show () para depurar esto. Bombea un ciclo de mensajes, perturbando el flujo normal de eventos. El evento Load se desencadena cuando Windows envía el mensaje WM_SHOWWINDOW, justo antes de que la ventana se vuelva visible. No hay notificaciones de Windows para "su ventana ahora se muestra completamente", por lo que los diseñadores de WF generaron un truco para generar el evento Mostrado . Utilizan Control.BeginInvoke (), asegurando que el método OnShown () se llame tan pronto como el programa vuelva a estar inactivo y vuelva a ingresar al ciclo de mensajes.

Este truco tiene muchos otros usos, particularmente cuando tienes que retrasar la ejecución del código iniciado por un evento. Sin embargo, en su caso se desmorona porque usa MessageBox.Show (). Su bucle de mensaje distribuye el delegado registrado con BeginInvoke (), lo que hace que se ejecute el evento Mostrado antes de que se muestre la ventana.

Hay muchas otras maneras de obtener diagnósticos más allá de MessageBox. Debug.Print () y Console.WriteLine () son útiles, su salida va a la ventana de salida de Visual Studio sin tener ningún efecto perjudicial en la secuencia de activación de eventos normales. Un breakpoint simple puede hacer maravillas también.


Ok, creo que ya he averiguado qué está pasando realmente y de dónde viene mi confusión (aunque no por qué se comporta de esa manera). Parece que el evento Mostrado realmente ocurre dentro del evento Load.

Dado este código:

protected override OnLoad(EventArgs e) { MessageBox.Show("Enter Load"); base.OnLoad(e); MessageBox.Show("Exit Load"); } protected override OnShown(EventArgs e) { MessageBox.Show("Enter Shown"); base.OnShown(e); MessageBox.Show("Exit Shown"); }

entonces los mensajes se muestran en este orden:

  1. Ingrese la carga
  2. Ingrese mostrado
  3. Salir se muestra
  4. Salir de la carga

La propiedad Visible es Verdadero en los cuatro casos, pero en ninguno de estos casos es la forma realmente visible en la pantalla (pintada).

Lo realmente extraño es que si hago un comentario sobre el cuadro de mensaje "Salir de la carga", entonces el formulario aparece en la pantalla antes de que aparezca el mensaje "Enter Shown". Parece ser código ejecutado después de la llamada base OnLoad que realmente se está oponiendo a algo.


Una cosa que sé con certeza es que el evento mostrado se ejecuta después de que todo en InitializeComponent haya terminado y el formulario aparezca y se muestre que debe colocar el código que mueve el objeto en el formulario en función de la ubicación de otro objeto

hacer una prueba rápida con un proyecto vacío:

Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load MsgBox("load") ''form is still visible = false End Sub Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown MsgBox("shown") '' form is now visible = true End Sub End Class


El evento Shown ocurre después del evento Load . La diferencia principal no está en la visibilidad de la forma, sino en su estado (ancho, alto, etc.).

Para aclarar, aquí hay un ejemplo. Considere un formulario que tiene un tamaño predeterminado de 100, 200 y un WindowState que está Maximized . En el controlador de eventos Load , el tamaño será 100, 200 . Pero en el controlador de eventos Shown , el tamaño será el tamaño de su pantalla .