在C#中移除事件处理程序

5

我正在开发一个Windows Forms应用程序,现在遇到了一些困难。

我有类似于MVC架构的东西。有时,我想让属于视图的控件停止监听事件。所以在视图代码中,我写了以下方法:

public void enableEventHandlers(bool enable)
{
    if (enable)
    {
        control.someEvent += someEventHandler;
    }
    else
    {
        control.someEvent -= someEventHandler;
    }
}

事情是这样的:当我想要删除事件处理程序时,只需将此方法作为参数调用false即可。如果我从视图代码内部调用此方法,它可以正常工作。但是如果我从控制器代码内部调用此方法,则无法正常工作(事件处理程序未被删除)。
为了提供更多背景信息:
这能正常工作:
public partial class View : Form
{
     public void enableEventHandlers(bool enable)
     {
         // The code I already showed
     }

     public void doSomething()
     {
         enableEventHandlers(false);
         // do something
         enableEventHandlers(true);
     }
 }

这个不起作用:

public class controller
{
     private View myView;

     public void doSomething()
     {
         myView.enableEventHandlers(false);
         // Do something... but somehow everything inside my Form is still paying attention to events
         myView.enableEventHandlers(true);
     }
}

这不是线程问题吗?所有GUI代码必须从主线程调用。你的控制器在不同的线程上吗? - AnthonyLambert
3
由于您的代码看起来应该可以实现您想要的功能,我认为我们需要更多的上下文信息。您能否尝试创建一个 mcve 以便我们可以重现这个问题? - René Vogt
此外,您可以在尝试删除事件处理程序之前检查它是否已注册。添加处理程序也是如此。确保当前没有处理程序注册。另外,您的表单是一个部分类。请检查初始化代码是否正在注册事件处理程序。最好完全避免使用WinForms开发中的设计器。只需创建一个子类Form的类并自己编写代码即可。这样您将更好地控制最终产品。您还应考虑您的UI设计。如果您必须像这样删除处理程序,则可能是错误的。 - ManoDestra
你的“控制”对象是什么,你在哪里创建这些实例? - CathalMF
你没有在异步执行任何操作吧?那可能会引起问题。 - Clint
@RenéVogt 感谢您的建议。我刚刚写了一个小例子,它按照我的意愿正常工作了。如果我找到导致问题的原因,我会发布更新,并继续修改我的项目代码。再次感谢您。 - Matías Juarez
2个回答

1

最终我找到了问题所在。似乎我在同一个控件上两次附加了事件处理程序。无论如何我都找不到确切的行号。我找到的解决方法是在添加新事件处理程序之前删除已有的事件处理程序。 现在,enableEventHandlers方法看起来像这样:

public void enableEventHandlers(bool enable) {
    if (enable)
    {
        control.someEvent -= someEventHandler;
        control.someEvent += someEventHandler;
    }
    else
    {
        control.someEvent -= someEventHandler;
    } 
}

感谢您的回答。

-2

我不确定是否是这个问题,但您没有初始化您的视图。您只是说“private View view”,但这并没有指向任何地方。您要么通过执行“private View v = new View()”创建一个新的View,要么让该视图指向您想要更改事件的视图。


1
所以他应该已经捕获了一个“NullReferenceException”,我相信他一定会告诉我们的。 - René Vogt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接