Pergunta

Como funciona o evento e.Cancel em caso FormClosing em um WinForm? Eu sei que você configurá-lo para True para cancelar o fechamento, mas em que ponto é que o processo de forma isso? Existe uma ação secundária tomada pela propriedade?

Como eu poderia implementar uma ação similar em um controle personalizado? (C # ou VB)

Nota:. Eu olhei para cerca de 30 minutos agora, e não conseguimos encontrar respostas no Google ou o SO procurar, então se é uma duplicata, meu mau

Foi útil?

Solução

Eu acho que o poster original pode estar se perguntando o que acontece quando alguns assinantes definir Cancel = false e alguns assinantes definir Cancel = true. Se este for o caso, então a pergunta "quando é que o processo de forma este" assume maior importância.

No começo eu me perguntava se o setter foi implementado para OU ou E cada valor. Usando refletor para inspecionar o setter para shows CancelEventArgs.Cancel ele simplesmente define um campo particular:

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

Então eu percebi que espreita em 'Form.OnClosing (CancelEventArgs args)' iria mostrar quando o valor estiver marcada, como as respostas anteriores, mas isso não é o que mostra refletor:

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

Então eu habilitado fonte de depuração e encontrou recebendo o delegado EVENT_CLOSING da coleção Events cai no fundo no API de janelas tal que handler na primeira linha de OnClosing é null quando os conjuntos de formulários Cancel = true, ou seja, o código gerenciado nunca realmente testa se CancelEventArgs.Cancel == true. Se você quiser a coragem feias do que acontece no interior do EventHandlerList, você recebe a seguinte:

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

Durante a depuração, parent.CanRaiseEventsInternal é falsa se o fechamento foi cancelado.

Então ... a implementação efectiva de cancelar o fechamento de um formulário é mais complicado do que as respostas anteriores, mas suas sugestões de como cancelar seus próprios eventos mostrar corretamente como fazê-lo em código gerenciado. Chame o CancelEventHandler e depois testar o valor de CancelEventArgs.Cancel depois de todos os assinantes de ter tido a chance de definir o valor para true. Isso ainda não responde o que acontece se alguns assinantes definir Cancel = false e alguns Cancel = true set. Alguém sabe? Será que algo como o seguinte ser exigido?

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

Outras dicas

Seguindo o padrão de geração de evento padrão usado no 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top