Вопрос

Как работает событие 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
   }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top