EventArgs取消如何在FormClosing事件中工作?

Ste*_*oni 3 .net event-handling eventargs winforms

e.Cancel事件如何在WinForm上的FormClosing事件中工作?我知道你把它设置True为取消关闭,但是表单在什么时候处理这​​个?该物业是否采取了次要行动?

如何在自定义控件中实现类似的操作?(C#或VB)

注意:我现在已经找了大约30分钟,但在谷歌或SO搜索中找不到任何答案,所以如果它是重复的,我的不好.

fli*_*ubt 7

我认为原始海报可能会想知道当一些用户设置Cancel = false和一些用户设置时会发生什么Cancel = true.如果是这种情况,则问题"表单何时处理此问题"具有更重要的意义.

起初我想知道是否将setter实现为OR或AND每个值.使用Reflector检查CancelEventArgs.Cancel显示的setter 它只是设置一个私有字段:

public bool Cancel
{
    get{ return this.cancel; }
    set{ this.cancel = value; }
}
Run Code Online (Sandbox Code Playgroud)

所以我想偷看'Form.OnClosing(CancelEventArgs args)'会在检查值时显示,就像之前的答案一样,但这不是Reflector所显示的:

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

所以我启用了源代码调试,并发现EVENT_CLOSINGEvents集合中获取代理深入到窗口API,这样handler在第一行OnClosingnull表单设置时Cancel = true,这意味着托管代码永远不会真正测试是否CancelEventArgs.Cancel == true.如果你想要了解EventHandlerList内部发生的丑陋内容,你会得到:

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

在调试时,parent.CanRaiseEventsInternal如果关闭被取消,则为false.

所以...取消表单关闭的实际实现比以前的答案更复杂,但他们对如何正确取消自己事件的建议显示了如何在托管代码中执行此操作.调用CancelEventHandler然后测试CancelEventArgs.Cancel所有订阅者有机会将值设置为的值true.如果某些用户设置了Cancel = false一些设置,这仍然无法解决会发生什么Cancel = true.有人知道吗?是否需要以下内容?

public bool Cancel
{
   get{ return this.cancel; }
   set{ this.cancel = this.cancel || value; } 
}
Run Code Online (Sandbox Code Playgroud)