取消订阅匿名委托事件

时间:2012-06-07 13:57:22

标签: c# events delegates anonymous

我在找出一种取消订阅某些匿名委托事件的方法时遇到了一些麻烦,我在预先制作的帮助文件中发现这些事件有助于在运行时移动控件。我想取消订阅这些事件的原因是控件(在这种情况下是按钮)将再次被锁定而无法移动。这是辅助类中的方法:

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

2 个答案:

答案 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;

或者将匿名方法转换为正确的方法。

答案 1 :(得分:1)

简而言之,您不能使用anonymous委托来执行此操作。

如果您希望从活动中取消取消订阅,请定义delegate/action并按照您推荐的模式进行操作。