Как EventArgs Cancel работает в событии FormClosing?
Как работает событие e.Cancel в событии FormClosing в WinForm? Я знаю, что вы установили его на True
отменить закрытие, но в какой момент форма обрабатывает это? Есть ли вторичные действия, предпринятые собственностью?
Как я могу реализовать подобное действие в пользовательском элементе управления? (C# или VB)
Примечание: я искал около 30 минут и не смог найти ни одного ответа в Google или поиске SO, так что, если это дубликат, мой плохой.
3 ответа
Я думаю, что оригинальный постер может задаваться вопросом, что происходит, когда некоторые подписчики устанавливают Cancel = false
и некоторые подписчики установлены Cancel = true
, Если это так, то вопрос "когда эта форма обрабатывает" приобретает большую важность.
Сначала я задавался вопросом, был ли установлен сеттер для ИЛИ или И для каждого значения. Использование Reflector для проверки правильности установки 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
является null
когда форма устанавливает 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;
}
}
Во время отладки, parent.CanRaiseEventsInternal
ложь, если закрытие было отменено.
Итак... фактическая реализация отмены закрытия формы сложнее, чем предыдущие ответы, но их предложения о том, как правильно отменить собственные события, показывают, как это сделать в управляемом коде. Вызовите CancelEventHandler и затем проверьте значение CancelEventArgs.Cancel
после того, как все подписчики имели возможность установить значение true
, Это все еще не отвечает, что происходит, если некоторые подписчики установлены Cancel = false
и какой-то набор Cancel = true
, Кто-нибудь знает? Требуется ли что-то вроде следующего?
public bool Cancel
{
get{ return this.cancel; }
set{ this.cancel = this.cancel || value; }
}
Следуя стандартному шаблону генерации событий, используемому в 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
}
}