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