使用lambda表达式的事件
我需要有人帮助我解决这个小问题。 这是一个代码片段:
void shuffle()
{
for (int i = 0; i < 4; i++) {
// here should be the computations of x and y
buttons[i].Click += (s, e) => { show_coordinates(x, y); };
// shuffling going on
}
}
void show_coordinates(int x, int y)
{
MessageBox.Show(x + " " + y);
}
正如你所看到的,我每次运行循环时都会为每个按钮创建一个新的事件处理程序,其中包含不同的x和y。 我的表单中还有另一个按钮,随机混合按钮。
所以问题在于:如果我按下shuffle按钮说10次,然后按任意混洗按钮,事件处理程序将堆叠起来,并且我会得到10个显示x和y值的消息框。
那么我怎么能每次按下shuffle时用新的事件处理程序覆盖之前的事件处理程序。
提前致谢。
我会重新设计代码,而不是像这样做:
private PointF[] points = new PointF[4];
//Run once
public void Initialize()
{
for (int i = 0; i < 4; i++)
buttons[i].Click += (s, e) => { show_coordinates(i); };
}
public void Shuffle()
{
for (int i = 0; i < 4; i++)
{
// here should be the computations of x and y
points[i] = new PointF(x,y);
// shuffling going on
}
}
public void show_coordinates(int index)
{
var point = points[index];
MessageBox.Show(point.X + " " + point.Y);
}
反射是一种方法,但我更喜欢委托并添加/删除该委托。 与使用反射相比,这会导致更易于维护的代码:
如何删除一个lambda事件处理程序
在for循环中,首先删除事件处理程序,然后重新添加它们。 但考虑到这是不好的做法。 你应该使用按钮的datacontext并将一个对象绑定到包含你的x和y值的对象。 这样你只需要附加一次你的事件处理程序。 而不是每次洗牌被调用。 然后更新你的按钮datacontext是更方便。
Example PseudoCode:
public MainWindow() {
ForEach Button addEvent(DoSomething);
ForEach Button Button.Datacontext = new Data();
}
public class Data {
prop X;
prop Y;
ctor(x,y)
ctor()
}
public void DoSomething()
{
var data = Button.datacontext as data
MessageBox(data.x, data.y)
}
public void Shuffle()
{
calc x, y
foreach Button (Button.datacontext as data).x = x, ...
}
链接地址: http://www.djcxy.com/p/51451.html
上一篇: Events with lambda expression
下一篇: Remove eventHandler that was added using lambda expression