Events with lambda expression

I need someone to help me with this little problem I have. Here's a code fragment:

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);
}

as you can see I create a new event handler with different x and y for each button every time I run the loop. There's another button in my form which shuffles the buttons randomly.

So here's the problem: If I press the shuffle button say 10 times and then press any of the shuffled buttons, event handlers stack up and I get 10 message boxes displaying x and y values.

So how can I overwrite the previous event handler with a new one each time I press shuffle.

Thanks in advance.


我会重新设计代码,而不是像这样做:

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);
}

Reflection is a one way to do it, but i would prefer a delegate and adding/removing that delegate. This leads to easier maintainable code than using a reflection:

How to remove a lambda event handler


In your for loop first remove the event handlers then re-add them. However take into account that this is bad practice. You should use the button's datacontext and bind an object to it containing your x and y values. This way you only have to attach your event handler once. Instead of every time shuffle get's called. Then updating your buttons datacontext is way more convenient.

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/51452.html

上一篇: 两个dispose实现之间的区别?

下一篇: 使用lambda表达式的事件