tierra secundarios sangre leyenda fuego elementos control aire agua aang .net winforms events user-controls

.net - secundarios - sangre control



¿Cómo capturo eventos de subcontroles en un control de usuario en una aplicación de WinForms? (5)

¿Hay alguna forma para que el formulario principal pueda interceptar eventos que se activan en un subcontrol en un control de usuario?

Tengo un control de usuario personalizado incrustado en el formulario principal de mi aplicación. El control contiene varios subcontroles que manipulan datos, que a su vez se muestran en otros controles en el formulario principal. Lo que me gustaría es si el formulario principal podría estar de alguna manera informado cuando el usuario cambie los subcontroles, por lo que podría actualizar los datos y la pantalla correspondiente en otro lugar.

En este momento, estoy haciendo trampa. Tengo un delegado conectado al evento de dejar foco de los subcontroles. Este delegado cambia una propiedad del control de usuario que no estoy utilizando en otro lugar (en este caso, CausesValidation). Luego tengo un delegado definido en el formulario principal para cuando cambia la propiedad CausesValidation del control de usuario, que luego dirige la aplicación para actualizar los datos y mostrarlos.

Surge un problema porque también tengo un delegado configurado para cuando el foco deja el control del usuario, porque necesito validar los campos en el control del usuario antes de poder permitir al usuario hacer cualquier otra cosa. Sin embargo, si el usuario solo está cambiando entre subcontroles, no quiero validar, porque es posible que no se haya terminado de editar.

Básicamente, quiero que los datos se actualicen cuando el usuario cambie de subconcesiones O deje el control del usuario, pero no valide. Cuando el usuario deja el control, quiero actualizar Y validar. En este momento, dejar el control de usuario hace que la validación se active dos veces.


El mejor modelo para este tipo de cosas será crear eventos personalizados en su control de usuario y subirlos en los momentos apropiados.

Su escenario es bastante complejo, pero no desconocido. (De hecho, estoy en un modo muy similar en uno de mis proyectos actuales). La forma en que lo abordo es que el control del usuario es responsable de su propia validación. No uso CausesValidation; en cambio, en el punto de control del usuario apropiado, realizo la validación a través de una anulación de ValidateChildren (). (Esto generalmente sucede cuando el usuario hace clic en "Guardar" o "Siguiente" en el control del usuario, para mí).

No estar familiarizado con su IU de control de usuario, puede no ser el enfoque correcto al 100% para usted. Sin embargo, si genera eventos personalizados (posiblemente con EventArgs personalizados que especifiquen si realizar o no la validación), debería poder llegar a donde desea estar.


Me gustaría decir que, como se describió, en realidad parece que estás persiguiendo a una red arenque. Si bien parece que tienes una situación en la que la falta de eventos burbujeantes en WinForms te está causando problemas, la realidad es que una arquitectura deficiente te está obligando a necesitar el burbujeo del evento cuando no deberías hacerlo.

Si puede refactorizar / reestructurar su diseño de manera que los controles funcionen con un modelo de datos común (MVC / MVP son opciones obvias), simplemente puede aplicar patrones comunes de WinForms como eventos PropertyChanged en el modelo para indicar su forma principal y cualquier otro control que consumen esos datos para actualizarse.

En resumen, las otras respuestas son razonables porque responden la pregunta como se les pidió. Pero desde el punto de vista de la calidad del código, creo que la mejor respuesta es separar sus datos de la IU.


Tendrá que conectar los eventos que le interesan para la captura dentro de su control de usuario y publicarlos a través de algunas propiedades de eventos personalizados en el control del usuario. Un ejemplo simple sería envolver un evento de clic de botón:

// CustomControl.cs // Assumes a Button ''myButton'' has been added through the designer // we need a delegate definition to type our event public delegate void ButtonClickHandler(object sender, EventArgs e); // declare the public event that other classes can subscribe to public event ButtonClickHandler ButtonClickEvent; // wire up the internal button click event to trigger our custom event this.myButton.Click += new System.EventHandler(this.myButton_Click); public void myButton_Click(object sender, EventArgs e) { if (ButtonClickEvent != null) { ButtonClickEvent(sender, e); } }

Luego, en el Formulario que usa ese control, conecta el evento como lo haría con cualquier otro:

// CustomForm.cs // Assumes a CustomControl ''myCustomControl'' has been added through the desinger this.myCustomControl.ButtonClickEvent += new System.EventHandler(this.myCustomControl_ButtonClickEvent); myCustomControl_ButtonClickEvent(object sender, EventArgs e) { // do something with the newly bubbled event }


En caso de que alguien todavía se esté preguntando cómo simular el burbujeo de eventos en WinForm, el método Application.AddMessageFilter es un buen lugar para mirar.

Con este método puede instalar su propio filtro que supervisa todos los mensajes que se publican en la cola de mensajes del hilo actual.

Debe tener en cuenta que los mensajes enviados (no publicados) no pueden ser manejados por este filtro. En última instancia, los eventos más interesantes (como los eventos de clic) se publican y no se envían y, por lo tanto, pueden ser monitoreados por este filtro


La mejor práctica sería exponer eventos en el UserControl que burbujean los eventos hasta la forma principal. He seguido adelante y he creado un ejemplo para ti. Aquí hay una descripción de lo que ofrece este ejemplo.

  • UserControl1
    • Crear un UserControl con TextBox1
    • Registre un evento público en UserControl llamado ControlChanged
    • Dentro del UserControl regístrese un controlador de eventos para TextBox1 TextChangedEvent
    • Dentro de la función del controlador TextChangeEvent llamo al evento ControlChanged para que salte a la forma padre
  • Form1
    • Coloque una instancia de UserControl1 en el diseñador
    • Registre un controlador de eventos en UserControl1 para MouseLeave y ControlChanged

Aquí hay una captura de pantalla que ilustra que el evento ControlChanged que definí en UserControl está disponible a través del UX en Visual Studio en el formulario padre de Windows.

Controladores de eventos para el control de usuario http://friendfeed.s3.amazonaws.com/0d5a3968cb785625c8afb3974a8d84894c476291