Como EventArgs Anular trabalho no Evento FormClosing?
-
11-09-2019 - |
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
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
}
}