2011-05-22 164 views
1

之前我推倒重來...如何處理順序調用事件處理程序?

這只是一個爲說明問題 - 讓我們說你有一些數據的收集和前端這顯示集合的一個項目後端。

在後端我有ItemIndex - 每當它發生變化,它就會觸發OnScroll事件。

我也有AddNewItem方法,它在集合的末尾添加新項目。該方法的結尾調用OnNewItem事件處理程序。

這裏是catch-in AddNewItem我必須改變ItemIndex,它會觸發OnScroll。 (!)OnScroll和OnNewItem的兩個接收者之一,如果前端顯示選定的項目。

在這種情況下,它被稱爲兩次(不好)。一種解決方案是改變item_index而不是ItemIndex,並且這樣防止OnScroll,但我不喜歡它,因爲ItemIndex不再作爲黑盒子。

是否有任何已建立的順序點火事件模式,並且只發送「重要」事件(這裏是:OnNewItem重寫OnScroll)?我的想法是定義一個事件範圍,然後不是直接發送事件,而是將它們註冊爲發送,並在範圍結束時對它們進行排序併發送所需的範圍。

一般 - 問題 - 我應該如何處理潛在的順序事件觸發。使用內部消息來避免發送冗餘事件?忽略開銷? ...?

+0

就像那個問題一樣。不知道這個我自己。我的解決方案始終是直接設置字段,或者有一些不會觸發事件的ItemIndexInternal。 – 2011-05-22 16:21:35

+0

也是我的,但是如果我的程序變得越來越大,這種方法將會成爲問題。 – greenoldman 2011-05-22 16:46:58

回答

2

答案似乎明顯,我athough我可以很容易地錯過了一些東西:

private bool IsAdding { get; set; } 
private int item_index; 
private IList m_collection; 

public void AddNewItem(object item) 
{ 
    if (item == null) 
    { 
     throw new Exception("Cannot add null item."); // little bit of contracting never hurts 
    } 

    m_collection.Add(item); 
    IsAdding = true; 
    ItemIndex = collection.Count - 1; //I'm just making assumptions about this piece but it is not important how you decide what your index is to answer the question 

    if (OnNewItem != null) 
    { 
     OnNewItem(this, EventArgs.Empty); 
    } 
} 

public int ItemIndex 
{ 
    get { return item_index =; } 
    set 
    { 
     item_index = value; 
     if (!IsAdding && OnScroll != null) //won't double fire event thanks to IsAdding 
     { 
      OnScroll(this, EventArgs.Empty); 
     } 
     IsAdding = false; //need to reset it 
    } 
} 

有一件事我要指出的是,你做的只是簡單的直接改變item_index提到但不會有黑箱行爲。那麼黑匣子是一切都很好......但這個術語只適用於與我們一直在討論的這個類交互的對象。

你應該感覺自己有權利使用自己班內的內部。黑箱內的項目不是很好的OOP。如果你這樣做,那麼你的班級可能有設計問題,它應該被分成多個班級。

+0

有關設計的好處,但我仍然更喜歡黑箱 - 加載,保存,添加,刪除等等,很容易錯過一些東西。最好花更多時間在更堅實的設計上,而不是尋找錯誤,因爲每種方法都會假設其他方法。我將使用你的想法與IsAdding,而是將其更改爲EventPending並檢查當前的優先級是否更大或更小。 – greenoldman 2011-05-22 16:51:25

+0

@macias給他自己= P你的命名約定可能會更有意義。很高興幫助。 – 2011-05-22 19:34:10

0

您可以將這兩個事件指向一個函數。該功能可以確定發件人並執行適當的操作。

+0

「點」是什麼意思? – greenoldman 2011-05-22 15:55:07

+0

只需像通常那樣爲代表分配一個功能即可。 – Jordan 2011-05-22 16:26:55

+0

我很抱歉,我不明白你在說什麼。我的代碼是ItemIndex = Items.Count-1; if(OnNewItem!= null)OnNewItem();你在哪裏看到另一位代表的位置? – greenoldman 2011-05-22 16:46:12

2

一個解決方案是使用某種形式的「鎖存器」。更新時,您通過幫助者執行UI操作,幫助者設置一個標誌,說'嗨,我處於特殊狀態!'。然後,在提高事件時,檢查是否設置了鎖定 - 如果是,則跳過提出這些事件。

它基本上是一個非常簡單的,馬修張貼的通用版本。根據情況,設置一個標誌可能綽綽有餘。

Jeremy Miller's explanation is worth reading