我现在正在写一个简单的国际象棋游戏。
在我的游戏中有#34; Chessfields"和"选项"。 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()
处理程序只会被调用一次。
但问题出现了: 当我然后单击一个选项字段(这样可能移动一个图形)时,所有最近点击的正常棋场都会移动到该字段,因为所有以前的处理程序仍处于活动状态,但我已经通过调用删除了它们:
foreach (MouseButtonEventHandler optionClickHandler in _recentOptionClickHandlers)
{
chessfield.MouseDown -= optionClickHandler;
}
我点击任何字段越多,调用的事件处理程序就越多(第一次:1个处理程序;第二次:2个处理程序;第三次:4个处理程序; ......)
这个问题确实让我疯狂了2天。
提前致谢
答案 0 :(得分:4)
现在无法测试,也无法发表评论,所以我会在这里回复。
我认为添加到_recentOptionClickHandlers
的处理程序与您注册MouseDown
事件的处理程序不同,因为您在创建新的delegate
之前将其添加到您的EventHandler evt = (sender, e) => Option_Click(sender, e, chessfield, SourceX, SourceY);
chessfield.MouseDown += evt;
_recentOptionClickHandlers.Add(evt);
列表。
你应该尝试这样的事情:
terraform apply