在封闭事件中的“e.Cancel”
使用FormClosing
事件时,为什么代码e.Cancel = true;
work,但是new CancelEventArgs().Cancel = true;
不起作用?
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { e.Cancel = true; new CancelEventArgs().Cancel = true; }
该事件由Winforms管道代码引发。 它可以看到自定义事件处理程序想要更改默认行为的唯一方法是通过e
对象。 创建一个新的CancelEventArgs对象没有管道可以检测到的副作用。
还有其他错误,为了外部代码的利益而提出事件,让它知道发生了什么,并给它一个改变行为的选项。 这里没有外部代码,事件处理程序实际上是引发事件的同一个类的一部分。 换句话说,表格正在聆听自己的事件。 有一个更好的方法来处理它,你覆盖引发事件的方法。 像这样:
protected override void OnFormClosing(FormClosingEventArgs e) { e.Cancel = true; base.OnFormClosing(e); }
现在,外部代码可以覆盖默认行为,在OnXxxx方法运行后引发事件。 您可以选择,如果您不希望外部代码覆盖该行为,只需交换这两个语句即可。
我认为代码完全按照它的说法行事; 缺少的是文字阅读。
为e.Cancel
分配新值时,您正在修改作为函数参数提供的e
。 事件处理程序函数完成后,此FormClosingEventArgs
实例(包括在事件处理程序中对其进行的任何更改)将可用于调用事件处理程序的任何代码。 在这种情况下,几乎可以肯定是Microsoft编写的Winforms代码。
另一方面,当您在该事件处理程序内部创建一个FormClosingEventArgs
类型的新实例并对其执行某些操作时,没有任何内容可以将该信息提供给调用者; 你需要一些明确的东西 。 由于调用者在事件处理程序完成后查看它传入的参数的值,因此您需要以某种方式用新创建的实例替换调用者看到的e
的内容。 在其他情况下,这样的结果可能作为返回值提供。
通常,对于某些类型T
, new T()
的结果是类型T
的实例。 因此,您可以使用表达式new T()
的结果,就像处理类型为T
的非null变量一样。 在您的特定情况下,您要为类型T
上的属性赋值(具体而言,是由此创建的该类型的实例)。 (有一种特殊情况,构造函数失败了,但是现在不要去那里;对于简单类型,这几乎意味着你处于如此可怕的境地,以至于你的程序在任何情况下都不可能继续运行。 )
这里重要的是,如果你没有将表达式new T()
本身的结果分配到任何地方,那么一旦语句完成,新创建的实例就会被抛弃(技术上变得难以访问)。 然后在稍后的某个时刻,.NET垃圾收集器启动并实际回收已分配的内存。 它与在一个函数中分配变量,从另一个函数调用该函数并尝试访问从第二个函数分配的变量并没有做任何事情来将变量从第一个函数传递到第二个函数实际上没有任何不同,除了这里只涉及一个function。
在事件处理程序中执行类似第二行代码的操作会非常不寻常,但如果调用构造函数有一些副作用(例如触发延迟加载), 则原则上可以有效。
这段代码肯定只是检查它
protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); if (PreClosingConfirmation() == System.Windows.Forms.DialogResult.Yes) { Dispose(true); Application.Exit(); } else { e.Cancel = true; } } private DialogResult PreClosingConfirmation() { DialogResult res = System.Windows.Forms.MessageBox.Show(" Do you want to quit? ", "Quit...", MessageBoxButtons.YesNo, MessageBoxIcon.Question); return res; }
快乐的编码
这是因为CancelEventArgs
是一个传递给代码中事件处理程序的对象引用。 幕后代码使用CancelEventArgs
对象引发FormClosing
,并且所有事件处理程序都接收相同的对象。 一旦所有处理程序轮到他们,后台代码将检查它发送的CancelEventArgs
对象,以查看其Cancel
属性是否设置为true
。 如果是,则它不会执行任何操作,并且FormClose
事件链将停止。 如果Cancel
为false
( CancelEventArgs
默认值),意味着它尚未设置为Cancel
事件链,则幕后代码继续进行,然后引发FormClosed
事件。
您可以在MSDN上的Form.FormClosing事件中阅读更多内容 。
在Forms
所有-ing事件通常后跟-ed事件。 -ing事件通常具有CancelEventArgs
,可以将其Cancel
属性设置为true
以阻止-ed事件发生。