3

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

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

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

4

3 回答 3

7

我认为原始发布者可能想知道当一些订阅者设置Cancel = false和一些订阅者设置时会发生什么Cancel = true。如果是这种情况,那么“表单什么时候处理这​​个”这个问题就显得更加重要了。

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

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

所以我想偷看'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);
    }
}

所以我启用了源代码调试,发现EVENT_CLOSING从集合中获取委托Events会深入到窗口 API 中,这样在表单设置handler的第一行中OnClosing,这意味着托管代码从不真正测试是否。如果您想了解 EventHandlerList 内部发生的情况,您会得到以下信息:nullCancel = trueCancelEventArgs.Cancel == true

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

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

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

public bool Cancel
{
   get{ return this.cancel; }
   set{ this.cancel = this.cancel || value; } 
}
于 2009-11-01T14:42:56.667 回答
2

遵循 Windows 窗体中使用的标准事件生成模式:

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
    //...
  }
}
于 2009-11-01T13:11:03.033 回答
0
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
   }
}
于 2009-10-31T20:02:34.690 回答