问题 如何确定某个特定代表是否已分配给某个活动?


我在winform上有一个命令按钮。所以,如果我有类似的东西:

myButton.Click += MyHandler1;
myButton.Click += MyHandler2;
myButton.Click += MyHandler3;

如何判断是否已将任何特定的MyHandler添加到Click事件中,以便它不会再添加到我的代码中的其他位置?

我已经阅读了如何使用GetInvocationList()来获取自己的事件信息。但是在尝试使用各种组合获取命令按钮的项目时出错。它说,

“事件   'System.Windows.Forms.Control.Click'   只能出现在左侧   + =或 - =。“

我错过了什么?

[编辑] - 我想强调一下 这个问题 艾哈迈德指出。这是一个kludge,应该更容易恕我直言,但看起来它可能只是工作。


6138
2017-11-04 02:36


起源

你不能。你能做的最好的事情是 myButton.Click -= MyHandler1 在添加之前。 - slugster
可能重复 确定绑定到事件的事件处理程序列表 - Ahmad Mageed
@Ahmad - 好眼睛。我肯定不会看到那个!但是,为清楚起见,我相信我的问题仍然有效。 - IAmAN00B


答案:


如果您对已添加的处理程序有疑问,请将其删除并重新添加。如果您的处理程序未首先添加,则会忽略您的删除。

myButton.Click -= MyHandler1;
myButton.Click += MyHandler1;

您还可以创建一个附加到事件的方法,并确保代码只运行一次。

private bool handlersAdded;
private void AddHandlers()
{
    if (this.handlersAdded) return;
    myButton.Click += MyHandler1;
    this.handlersAdded = true;
}

11
2017-11-04 07:28



不适合静态事件.. - sotn
@sotn为什么不呢?如果您有静态事件,我们称之为“StaticClick”,您仍然可以删除并添加处理程序: MyStaticClass.StaticClick-=MyHandler1;。它只是您从列表中删除和/或添加的方法指针。无论如何,我永远不会使用静态事件,如果你发现自己需要这样的东西,那么重新考虑你的设计。 - Paw Baltzersen
它可能不是“你的”设计,而是你使用的第三方dll。想想这个例子:你想要将一个事件处理程序附加到你的pc的声音驱动程序并将一些数据流传输到几个IP。该事件处理程序将是静态的,因为您不希望为每个ip创建多个侦听器,而是创建单个事件侦听器并从那里广播它(由于性能原因)。你建议删除该处理程序并为每个IP重新附加它。危险。我希望你理解我的观点。 - sotn


GetIvocationList的使用只能在事件的所有者(在你的情况下是myButton)中完成,这是事件背后的一个想法(而不是委托)。

像Slugster说的那样,你无法从myButton外部检查调用列表,但是你可以在添加之前尝试删除MyHandler#。


3
2017-11-04 02:50