2017-04-12 106 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! –