2012-06-07 117 views
2

我在解决一些匿名委托事件时存在一些麻烦,这些匿名委托事件是在预先创建的帮助文件中发现的,该文件有助于在运行时移动控件。我想取消订阅这些事件的原因是,控件(在本例中为按钮)将再次被锁定,无法移动。这里是辅助类的方法:退订匿名代理事件

public static void Init(Control control) 
    { 
     Init(control, Direction.Any); 
    } 

    public static void Init(Control control, Direction direction) 
    { 
     Init(control, control, direction); 
    } 

public static void Init(Control control, Control container, Direction direction) 
    { 
     bool Dragging = false; 
     Point DragStart = Point.Empty; 

     control.MouseDown += delegate(object sender, MouseEventArgs e) 
     { 
      Dragging = true; 
      DragStart = new Point(e.X, e.Y); 
      control.Capture = true; 
     }; 
     control.MouseUp += delegate(object sender, MouseEventArgs e) 
     { 
      Dragging = false; 
      control.Capture = false; 
     }; 
     control.MouseMove += delegate(object sender, MouseEventArgs e) 
     { 
      if (Dragging) 
      { 
       if (direction != Direction.Vertical) 
        container.Left = Math.Max(0, e.X + container.Left - DragStart.X); 
       if (direction != Direction.Horizontal) 
        container.Top = Math.Max(0, e.Y + container.Top - DragStart.Y); 
      } 
     }; 

    } 

这里是我如何通过调用方法订阅这些事件;

ControlMover.Init(this.Controls["btn" + i]); 

我读过有关MSDN上的一些方法有关创建一个局部变量持有这些事件,然后通过这样的方式退订退订这些,但我似乎无法在我自己的项目得到这个工作。我该如何解除这些事件,以便我的控件再次固定到位?

+0

你可以发布你的代码,在哪里存储他们在一个变量,并使用它来取消订阅? – CodesInChaos

+1

但个人而言,我会为此使用命名方法。更简单,更清洁的代码IMO。 – CodesInChaos

+0

我已经删除了这个,因为我什至不能远程工作。我会尝试检索一些或进一步的工作,但它看起来不太好! –

回答

5

匿名代理并不保证如编译器创建时那样是唯一的,当取消订阅相同代码的唯一性缺乏将导致它无法取消订阅正确的处理程序。唯一安全的做法是保留对委托的引用并使用它来取消订阅,或者将其更改为完整的方法。

我相信代表基于对象实例和方法签名是相等的。

可能重复:

How to remove a lambda event handler

基本上保持一个参考:

MouseEventHandler handler = (sender, e) => 
     { 
      Dragging = true; 
      DragStart = new Point(e.X, e.Y); 
      control.Capture = true; 
     }; 

control.MouseDown += handler; 
control.MouseDown -= handler; 

或关闭匿名方法到合适的方法。

+0

为您的输入欢呼。我认为,为了让事情变得更容易,从长远来看,我会把它们变成适当的方法。 –

+0

@ Shane'Shamus'Coulter我会,它也将使您的注册代码更清洁一点:'control.MouseDown + = MouseDownHandler;' –

+0

所以事实证明,我实际上很努力使他们正确的方法,因为所有传递类中的参数.. –

0

总之,你不能这样做anonymous代表。

如果您想要从事件取得订阅取消订阅,请定义delegate/action并按照您引用的模式进行操作。