使用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