Pregunta

¿Cómo funciona el evento e.Cancel en caso FormClosing en un WinForm? Sé que lo establece en True para cancelar el cierre, pero ¿en qué momento del proceso de forma esto? ¿Hay una acción secundaria adoptada por la propiedad?

¿Cómo podría implementar una acción similar en un control personalizado? (C # o VB)

Nota: He buscado durante unos 30 minutos ahora y no pude encontrar ninguna respuesta en Google o en la SO buscar, así que si es un duplicado, mi mal

.
¿Fue útil?

Solución

Creo que el cartel original que se pregunte lo que sucede cuando algunos suscriptores establecen Cancel = false y algunos abonados establecen Cancel = true. Si este es el caso, entonces la pregunta "¿Cuándo el proceso de forma esta" adquiere más importancia.

Al principio se preguntaron si el colocador se implementó para OR o AND cada valor. Utilizando Reflector para inspeccionar el colocador de CancelEventArgs.Cancel muestra que simplemente establece un campo privado:

public bool Cancel
{
    get{ return this.cancel; }
    set{ this.cancel = value; }
}

Así que pensé que mira a escondidas en 'Form.OnClosing (CancelEventArgs args)' mostraría cuando se comprueba el valor, al igual que las respuestas anteriores, pero eso no es lo que muestra reflector:

[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnClosing(CancelEventArgs e)
{
    CancelEventHandler handler = (CancelEventHandler) base.Events[EVENT_CLOSING];
    if (handler != null)
    {
        handler(this, e);
    }
}

Así que habilitada la depuración fuente y encontré conseguir el delegado EVENT_CLOSING de la colección Events cae profundamente en la API de ventanas tal que handler en la primera línea de OnClosing es null cuando la forma fija Cancel = true, es decir, el código administrado en realidad nunca comprueba si CancelEventArgs.Cancel == true. Si desea que las feas entrañas de lo que ocurre en el interior del EventHandlerList, se obtiene lo siguiente:

get { 
    ListEntry e = null;
    if (parent == null || parent.CanRaiseEventsInternal) 
    {
        e = Find(key);
    }
    if (e != null) { 
        return e.handler;
    } 
    else { 
        return null;
    } 
}

Durante la depuración, parent.CanRaiseEventsInternal es falso si el cierre fue cancelada.

Así que ... la implementación real de cancelar el cierre de una forma es más complicada que las respuestas anteriores, pero sus sugerencias sobre cómo cancelar sus propios eventos muestra correctamente cómo hacerlo en código administrado. Llame a la CancelEventHandler y luego probar el valor de CancelEventArgs.Cancel después de que todos los abonados han tenido la oportunidad de establecer el valor en true. Esto todavía no responde a lo que ocurre si algunos abonados establecen Cancel = false y algún conjunto Cancel = true. ¿Alguien sabe? Sería necesario algo como lo siguiente?

public bool Cancel
{
   get{ return this.cancel; }
   set{ this.cancel = this.cancel || value; } 
}

Otros consejos

Siguiendo el patrón de generación de eventos estándar utilizado en Windows Forms:

public event CancelEventHandler MyEvent;

protected void OnMyEvent(CancelEventArgs e) {
  CancelEventHandler handler = MyEvent;
  if (handler != null) {
    handler(this, e);
  }
}

private void button1_Click(object sender, EventArgs e) {
  CancelEventArgs args = new CancelEventArgs();
  OnMyEvent(args);
  if (!args.Cancel) {
    // Client code didn't cancel, do your stuff
    //...
  }
}
function OnMyCancelableEvent()
{
   var handler = CancelableEvent;
   var args = new CancelEventArgs()
   if(handler != null)
   {
        handler(this, args)
        if(args.Canceled)
           // do my cancel logic
        else
           // do stuff
   }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top