0

我正在以这种方式订阅一个活动:

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

我怎样才能在不同的范围内取消订阅?(但在范围内s1

我尝试了以下方法:

s1.MouseUp = null;



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



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

但是事件仍在触发,这怎么办?

4

5 回答 5

7

不要使用匿名事件,而是使用命名事件。

 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;  
 }
于 2013-07-05T12:24:59.740 回答
5

不要使用 lambda 创建匿名事件处理程序。

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;
}
于 2013-07-05T12:25:29.607 回答
3

您必须确保取消订阅您订阅的同一个处理程序,例如:

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

s1.MouseUp += handler;

后来:

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

当然,如果您要这样做,那么首先简单地使用成员方法可能要容易得多,正如其他答案所建议的那样。

于 2013-07-05T12:26:45.797 回答
1

这不会取消订阅事件,因为不能保证匿名方法编译成完全相同的东西,这会影响对事件取消订阅的相等性检查,导致它们“失败”删除订阅。

匿名方法不像匿名类型,如果类型已经存在,编译器将使用相同的类型定义。

使事件处理程序成为常规方法,或将匿名方法存储在局部变量中并取消订阅。

于 2013-07-05T12:25:51.760 回答
0

如果你真的需要一个 lambda(因为事件的执行上下文),你可以这样做:

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;
于 2013-07-05T12:28:09.533 回答