winforms - resolucion - ¿La mejor forma de suspender eventos de control en Windows Forms?
propiedades de un formulario en c# (6)
De tu otra pregunta, voy a adivinar que estás usando VB .NET. Por lo tanto, RemoveHandler es tu mejor opción. Normalmente en VB las personas configuran controladores de eventos usando la cláusula Handles. Pero también puedes hacerlo de esta manera:
AddHandler chk1.CheckedChanged, AddressOf DoSomething
donde DoSomething podría verse así:
Private Sub DoSomething(ByVal sender As Object, ByVal e As EventArgs)
'' whatever
End Sub
AddHandler conecta el evento, por lo que se disparará. Para que no se dispare, use RemoveHandler:
RemoveHandler chk1.CheckedChanged, AddressOf DoSomething
Antes de actualizar las casillas de verificación de la propiedad de sus hijos, llame a RemoveHandler en cada uno de ellos; luego, cuando haya terminado, llame a AddHandler para volver a colocar los controladores de eventos. Si todas sus casillas de verificación usan el mismo controlador, puede ponerlas en una colección y recorrer la colección para agregar o eliminar los manejadores.
Esto parece un problema muy simple y muy común. El ejemplo más simple que puedo pensar es este:
El formulario tiene cinco casillas de verificación con una casilla de verificación "marcar todo / no marcar ninguna" encima de ellos. Cuando un usuario selecciona la marcación de todas las casillas, alternar los estados de los "niños" - obviamente no quiero disparar los eventos de verificación de todos los niños hasta que termine de configurar todas las casillas de verificación.
No puedo encontrar un evento de control de suspensión en todo el formulario. Si simplemente me falta algo, entonces una gran respuesta simple. Salvo una solución simple que me falta, ¿cuál es la mejor forma (¿solución aceptada por la mejor práctica?) Para suspender los eventos de control de formulario.
Lo que hago en estos casos en lugar de tener un valor booleano que suspende eventos, uso un contador. Cuando el recuento es> 0, suspenda los eventos, cuando el recuento = 0, luego reanude los eventos. Esto ayuda con el problema si tengo varias cosas que podrían solicitar una suspensión de eventos.
La otra cosa útil es si necesito suspender eventos en un bloque, creo una pequeña clase de ayuda que es IDisposable que puedo usar en un bloque "usar" (en C #) así que no me olvide de disminuir el contador una vez que estoy fuera de mi alcance
También podría considerar el manejo de eventos de "clic" para los botones, en lugar de controlarlos. Eso podría estar más cerca de tu intención.
En mi aplicación Visual Basic 6.0 tuve que manejar usuarios haciendo doble clic en todo , así que en todos mis controladores de eventos tengo una línea que verifica una variable global
Private bSuspendEvents as Boolean
Private Sub Button1_Click()
On Error Goto ErrorHandler
If bSuspendEvents then Exit Sub
bSuspendEvents = True
''Do stuff
NormalExit:
bSuspendEvents = False
Exit Sub
ErrorHandler:
''Handle Error
Resume NormalExit
End Sub
Me he encontrado con esto antes y, por lo general, veo que la gente hace esto:
/*SNIP*/
private bool isMassUpdate;
public void Check1_Check(object sender, EventArgs e)
{
if(!isMassUpdate)
{
do some stuff
}
}
/*SNIP*/
También puede separar y volver a conectar los controladores de eventos, sin embargo, me dijeron que esto puede ser una fuente de pérdidas de memoria.
Información sobre pérdidas de memoria y controladores de eventos: no están directamente vinculados a la conexión y separación, pero hemos visto en una de nuestras aplicaciones que la mala referencia de los manejadores de eventos por los árboles de herencia puede causarla.
Consulte Pregunta de desbordamiento de pila ¿ Cómo ignoro la activación de eventos simples al cambiar los estados de control en C # Windows Forms?
Para el caso más general, si tiene relaciones complejas entre los controles, puede verificar qué control desencadenó el evento al verificar su propia propiedad Enfocada ... cada objeto solo depende de sí mismo.