2010-03-19 15 views
8

Tengo una casilla de verificación y me he suscrito al evento CheckedChanged. El controlador hace algunas operaciones allí. Marque y desmarque la casilla de verificación programáticamente (por ejemplo, chkbx_Name.Checked = true) y se desencadena el evento CheckedChanged.Problema en el evento CheckedChanged

Quiero que se active este evento solo cuando lo controlo manualmente o lo desactivo. ¿Hay alguna forma de evitar disparar este evento cuando lo marque/desmarque programáticamente?

Respuesta

13

darse de baja del evento antes de configurar:

check1.CheckChanged -= check1_CheckChanged; 

entonces se puede establecer mediante programación el valor de la casilla de verificación sin disparar su caso CheckChanged:

check1.Checked = true; 

continuación, volver a suscribirse:

check1.CheckChanged += check1_CheckChanged; 

[EDIT: March 29, 2012]

El problema con el enfoque de Tanvi es lo necesario para disfrutar de toda fuente de comprobación manual o desactive. No es que haya demasiados (solo al hacer clic con el mouse y al presionar la barra espaciadora), pero debe considerar invocar un evento refactorizado desde MouseClick y KeyUp (detectando la barra espaciadora)

Es más ordenado para un CheckBox (cualquier control para eso importa) para ser independiente de la fuente de entrada del usuario (teclado, mouse, etc.), así que para esto solo haré que la configuración programática de CheckBox sea realmente programática. Por ejemplo, se puede envolver el ajuste programático de la propiedad a un método de extensión:

static class Helper 
{ 
    public static void SetCheckProgrammatically(
     this CheckBox c, 
     EventHandler subscribedEvent, bool b) 
    {    
     c.CheckedChanged -= subscribedEvent; // unsubscribe 
     c.Checked = b; 
     c.CheckedChanged += subscribedEvent; // subscribe 
    } 
} 

Con este enfoque, el código puede responder perfectamente a la entrada de la entrada del ratón y el teclado de tanto usuario a través de un evento solamente, es decir, a través de CheckChanged. No hay duplicación de código, no es necesario suscribirse a múltiples eventos (por ejemplo, teclado, marcar/desmarcar CheckBox presionando la barra espaciadora)

+0

Me gusta esta solución, pero si hay varios codificadores en un proyecto determinado, ¿no sería necesario que todos se retiraran cada vez que cambiaran esta propiedad? – Coops

+0

envuélvalo con propiedades de extensión, er .. métodos de extensión. p.ej. check1.SetCheckedRaw (booleanHere) –

5

No. Los eventos de cambio de propiedad se activan cada vez que cambia el valor de la propiedad, independientemente de si esto fue realizado por su código, mediante el código o el enlace de datos del control. Es la misma ruta de código, por lo general.

Lo que puede hacer, sin embargo, si su controlador de eventos reside en la misma clase que el código que cambia el valor de la propiedad, es introducir un campo booleano privado en la clase que utiliza como indicador de si la propiedad actual el cambio es provocado por su código o por el usuario. Después de tu cambio, simplemente reinícialo. El controlador de eventos sería luego buscar en el campo y decidir si se debe hacer algo o no:

class Foo : Form { 
    private bool checkedProgrammatically = false; 

    void someMethod() { 
     // ... 
     checkedProgrammatically = true; 
     checkBox1.Checked = true; 
     checkedProgrammatically = false; 
     // ... 
    } 

    private void checkBox1_CheckChanged(object sender, EventArgs e) { 
     if (checkedProgrammatically) return; 
     // ... 
    } 
} 
0

Puede configurar variable booleana antes de cambiar el valor programiticaly, y comprobar que restablecer esa variable en caso CheckedChanged

1

Lo siento, no puedo comentar la respuesta de Michael Buen porque soy nuevo aquí (sin reputación), pero por lo que vale, prefiero su solución a la de Johannes Rössel por un par de razones.

1) la variable checkedProgrammatically es un poco demasiado cercana a la global para mí. No hay nada que impida que otro método lo configure accidentalmente como verdadero, lo que hace que se detengan todos tus eventos.

2) puede terminar con muchas variables dependiendo de la cantidad de eventos que está tratando. Sería fácil cambiar el incorrecto y los resultados pueden ser difíciles de depurar.

3) es más obvio lo que estás haciendo cuando cancelas la suscripción y luego vuelves a suscribirte. Toda la lógica está ahí, y no necesita cambiar sus manejadores de eventos para salir temprano dependiendo de ciertas condiciones.

He usado ambos métodos extensamente y encuentro que Michael es mucho más fácil a largo plazo.

1

Puede usar el evento MouseClick y en esa comprobación comprobar el estado de la casilla de verificación. De esta manera no se activará de forma programática, solo se invocará cuando el usuario active o desactive manualmente la casilla de verificación.

+1

¿Qué pasará si el usuario marca/desmarca CheckBox a través de la barra espaciadora? no del mouse? Ver mi solución propuesta –

Cuestiones relacionadas