2017-04-12 149 views
0

我正在寫一個簡單的國際象棋遊戲。C#Event Handlers越來越多

在我的遊戲中有「Chessfields」和「Options」。 Chessfield是棋盤上的每一塊場地,一個選項就是一舉一動 - 在場上有一個人物的可能性。

所以,當我點擊一個棋子,爲每個選項字段綁定一個新的事件處理程序。

像這樣:

private void Chessfield_Click(object sender, MouseButtonEventArgs e) 
{ 
    // ... some other stuff 

    PlaceOptions(); 

    // ... some other stuff 
} 

當函數PlaceOptions()做到這一點:

private void PlaceOptions(List<(int, int)> Options, int SourceX, int SourceY) 
{ 
    foreach ((int, int) option in Options) 
    { 
     // ... some other stuff 

     chessfield.MouseDown -= Chessfield_Click; 

     // should remove all existing handlers for that field 
     foreach (MouseButtonEventHandler optionClickHandler in _recentOptionClickHandlers) 
     { 
      chessfield.MouseDown -= optionClickHandler; 
     } 

     chessfield.MouseDown += (sender, e) => Option_Click(sender, e, chessfield, SourceX, SourceY); 
     _recentOptionClickHandlers.Add((sender, e) => Option_Click(sender, e, chessfield, SourceX, SourceY)); 

     // ... some other stuff 
    } 
} 

_recentOptionClickHandlers是存儲每一個處理我添加到任何選項字段的全局變量:

private List<MouseButtonEventHandler> _recentOptionClickHandlers = new List<MouseButtonEventHandler>(); 

現在:每當我點擊一個棋子,Chessfield_Click()處理程序只被調用一次。

但問題來了: 當我然後點擊一個選項字段(這樣的圖形的可能移動),所有最近點擊正常chessfields獲得移動到現場,因爲所有前面的處理仍活躍,但我媒體鏈接刪除他們致電:

foreach (MouseButtonEventHandler optionClickHandler in _recentOptionClickHandlers) 
{ 
    chessfield.MouseDown -= optionClickHandler; 
} 

而更多的我點擊任何領域,更多的事件處理程序獲取調用(第1次:1點的處理程序;第二次:2個處理器;第三次:4個處理器; ...)

這個問題真的讓我瘋狂,因爲2現在幾天。

在此先感謝

+0

也許你已經發明瞭一種新型的棋?社交象棋,當你移動一塊棋子時,所有棋子都移動到那裏:)所有的笑話都放在一邊,注意你寫的每個地方'(sender,e)=> Option_Click(...)'你正在創建一個新的實例,所以基本上你要爲MouseDown添加一個這樣的實例,並將另一個這樣的實例添加到'_recentOptionClickHandlers',確保你在這兩個中使用了相同的實例,我認爲你應該沒問題。 –

+1

你正在做一個lamda ..你的mousedown + =和你最近的選項按鈕處理程序+ =沒有指向相同的對象 – BugFinder

+0

所以當我這樣做:'MouseButtonEventHandler optionClickHandler =(sender,e)=> Option_Click(sender,e,chessfield, SourceX,SourceY);'之前,並使用此對象兩次,它應該罰款? –

回答

4

現在不能測試它也不能發表評論,所以我會在這裏回答。

我認爲處理程序添加到_recentOptionClickHandlers是不一樣的,你要註冊爲MouseDown事件,因爲你將它添加到你的列表之前創建一個新的delegate

你應該嘗試這樣的事:

EventHandler evt = (sender, e) => Option_Click(sender, e, chessfield, SourceX, SourceY); 
chessfield.MouseDown += evt; 
_recentOptionClickHandlers.Add(evt); 
+0

這正是我所需要的,感謝@STT和@BugFinder! –