0

I'm subscribing to an event this way:

  s1.MouseUp += (s, e) =>
  {
  indexOfPointToMove = -1;
  s1.LineStyle = LineStyle.Solid;
  MyModel.RefreshPlot(false);
   e.Handled = true;
 };

How could I unsubscribe in different scope? (but in scope of s1)

I've tried the following:

s1.MouseUp = null;



s1.MouseUp -=(s,e) =>
 {
       indexOfPointToMove = -1;
       s1.LineStyle = LineStyle.Solid;
       MyModel.RefreshPlot(false);
       e.Handled = true;
  };



s1.MouseUp += (s,e) =>
{
//nothing
};

But the event is still firing, how can this be done?

Sturm
  • 3,968
  • 10
  • 48
  • 78

5 Answers5

7

Do not use anonymous events but named ones.

 s1.MouseUp += Mouse_Up;

 s1.MouseUp -=Mouse_Up;

 void Mouse_Up(object sender, MouseEventArgs ea)
 {  
    indexOfPointToMove = -1;   
    s1.LineStyle = LineStyle.Solid;  
    MyModel.RefreshPlot(false);    
    e.Handled = true;  
 }
Nikola Davidovic
  • 8,556
  • 1
  • 27
  • 33
5

Do not use lambda to create anonymous event handler.

s1.MouseUp += s1_MouseUp; //subscribe
s1.MouseUp -= s1_MouseUp; //ussubscribe


private void s1_MouseUp(object sender, MouseEventArgs e)
{
   var s1 = (ListBox)sender; //cast it to proper object
   indexOfPointToMove = -1;
   s1.LineStyle = LineStyle.Solid;
   MyModel.RefreshPlot(false);
   e.Handled = true;
}
gzaxx
  • 17,312
  • 2
  • 36
  • 54
  • Thanks! But I can't subscribe to an event that way because I'm inside a loop in a method! And I can't create it outside because I can't reference s1. What can be done here? – Sturm Jul 05 '13 at 12:44
  • @Sturm Do you mean that the compiler is capturing some local variables so that this example doesn't compile? If so, which one(s)? – Tim S. Jul 05 '13 at 12:51
  • Check my edited answer. You can access `s1` in event by casting `sender` to proepr object – gzaxx Jul 05 '13 at 12:51
3

You must make sure to unsubscribe the same handler you are subscribing, for example:

MouseEventHandler handler = (s, e) =>
{
    indexOfPointToMove = -1;
    s1.LineStyle = LineStyle.Solid;
    MyModel.RefreshPlot(false);
    e.Handled = true;
};

s1.MouseUp += handler;

And later on:

s1.MouseUp -= handler; // you must have kept a reference to this somewhere

Of course if you are going to do this, it's probably much easier to simply use a member method in the first place as other answers suggest.

Jon
  • 428,835
  • 81
  • 738
  • 806
1

This won't unsubscribe the event because anonymous methods are not guaranteed to compile into exactly the same thing, this affects equality checks on event unsubscribing causing them to "fail" to remove the subscription.

Anonymous methods are not like anonymous types where the compiler will use the same definition of a type if the type already exists.

Make the event handler a regular method, or store the anonymous method in a local variable and unsubscribe from that instead.

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
0

If you really need a lambda (because of the execution context of the event), you can do it this way :

var act = new Action<object, EventArgs>((e, s) =>
    {
        indexOfPointToMove = -1;
        s1.LineStyle = LineStyle.Solid;
        MyModel.RefreshPlot(false);
        e.Handled = true;
    });

this.MouseUp += act;

...

this.MouseUp -= act;
Larry
  • 17,605
  • 9
  • 77
  • 106