2009-10-31 33 views
3

e.Cancel事件在WinForm的FormClosing事件中如何工作?我知道你將它設置爲True來取消關閉,但是表單在什麼時候處理?該物業是否採取了次要措施?EventArgs在FormClosing事件中如何取消工作?

如何在自定義控件中實現類似的操作? (C#或VB)

注意:我已經找了大約30分鐘了,並且在Google或SO搜索中找不到任何答案,所以如果它是重複的,我的不好。

+0

也http://stackoverflow.com/questions/295254/how-do-i-implement-a-cancelable-event見 – 2009-10-31 20:40:39

回答

7

我認爲原來的海報可能會奇怪,當一些用戶設置Cancel = false和一些用戶設置Cancel = true會發生什麼。如果是這種情況,那麼「表單何時處理這個問題」的問題變得更加重要。

起初我想知道二傳手是否實施或或每個值。使用Reflector檢查的制定者CancelEventArgs.Cancel顯示它只是設置一個私有字段:

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

所以我偷看「Form.OnClosing(CancelEventArgs參數)」當值被選中,像以前的答案會顯示,但是這不是什麼反射器顯示:

[EditorBrowsable(EditorBrowsableState.Advanced)] 
protected virtual void OnClosing(CancelEventArgs e) 
{ 
    CancelEventHandler handler = (CancelEventHandler) base.Events[EVENT_CLOSING]; 
    if (handler != null) 
    { 
     handler(this, e); 
    } 
} 

所以我啓用了源代碼調試,發現從Events收集得到EVENT_CLOSING委託滴深處到窗口API,使得handlerOnClosing第一行是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是假的,如果關閉被取消。

所以...取消窗體的關閉的實際執行情況比以前的答案比較複雜,但他們對如何取消自己的事件的建議正確顯示如何做到這一點的託管代碼。在所有訂閱者有機會將值設置爲true後,調用CancelEventHandler,然後測試CancelEventArgs.Cancel的值。如果某些訂戶設置了Cancel = false和某些設置Cancel = true,這仍然不會回答。有人知道嗎?是否需要如下所示?

public bool Cancel 
{ 
    get{ return this.cancel; } 
    set{ this.cancel = this.cancel || value; } 
} 
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 
    } 
} 
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 
    //... 
    } 
} 
+0

謝謝你向我展示瞭如何實現這一點。 – Stevoni 2009-11-01 16:45:30