取消订阅匿名委托事件

本文关键字:事件 取消 | 更新日期: 2023-09-27 18:36:25

我在找出一种取消订阅一些匿名委托事件的方法时遇到了一些麻烦,这些事件是我在预制的帮助程序文件中发现的,该文件有助于允许在运行时移动控件。我想取消订阅这些事件的原因是,控件(在本例中为按钮)将再次锁定并且无法移动。下面是帮助程序类中的方法:

 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 上阅读了一些关于通过创建一个保存这些事件的局部变量然后通过这种方式取消订阅这些的方法,但我似乎无法在我自己的项目中使用它。如何取消订阅这些事件,以便我的控件再次固定在适当的位置?

取消订阅匿名委托事件

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

我相信,基于对象实例和方法签名,委托是平等的。

可能的重复项:

如何删除 lambda 事件处理程序

基本上,保留一个参考:

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

或者将匿名方法变成正确的方法。

简而言之,你不能用anonymous委托来做到这一点。

如果您希望具有取消订阅事件的权限,请定义一个delegate/action并遵循您引用的模式。