【问题标题】:How do I find out if a particular delegate has already been assigned to an event?如何确定某个特定代表是否已被分配给某个活动?
【发布时间】:2010-11-04 02:36:43
【问题描述】:

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

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

如何判断是否有任何特定的 MyHandler 已添加到 Click 事件中,这样它就不会在我的代码中的其他地方再次添加?

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

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

我错过了什么?

[编辑] - 我想强调 Ahmad 指出的 this question。这是一个混乱,应该更容易恕我直言,但看起来它可能只是工作。

【问题讨论】:

  • 你不能。您可以做的最好的事情是在添加之前myButton.Click -= MyHandler1
  • @Ahmad - 好眼力。我肯定不会看到那个!但是,为了清楚起见,我相信我的问题仍然有效。

标签: c# winforms reflection delegates invocation


【解决方案1】:

如果您不确定您的处理程序是否已添加,则只需将其删除并重新添加即可。如果您的处理程序一开始没有被添加,您的删除将被忽略。

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

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

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

【讨论】:

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

GetIvocationList 的使用只能在事件的所有者(在您的情况下为 myButton)内部完成,这是事件背后的想法之一(与委托相反)。

就像 Slugster 说的,你不能从 myButton 外部检查调用列表,但你可以在添加之前尝试删除 MyHandler#。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2016-05-27
    相关资源
    最近更新 更多