是否可以多次将一个控件订阅到同一个事件处理程序?

时间:2010-12-29 07:59:51

标签: c# .net winforms events event-handling

我想知道是否将TextChanged事件处理程序绑定到TextBox控件,那么如何确保不允许再次绑定此事件处理程序?

3 个答案:

答案 0 :(得分:3)

您无法确保。理论上,您可以多次将同一事件处理程序绑定到文本框(或其他控件)。事件允许您做的唯一事情是添加处理程序并删除处理程序 - 没有提供额外的方法来检查现有订阅者。如果你不相信我,Jon Skeet在the authoritative answer提供了his article on events

如果您需要确保不会意外地将控件订阅两次同一事件,您需要自己跟踪它。老实说,你永远不应该在你不知道订阅了哪些事件处理程序的情况下结束。这不仅反映了草率设计,而且还可能意味着当您不再需要事件处理程序时,您不会小心删除

this question的答案中提供了一个可能的解决方案,但我提醒您不要盲目地使用此类内容。正如其他人所说,这段代码是一种反模式。

答案 1 :(得分:0)

您可以根据需要以编程方式绑定它。如果您想阻止这种情况,可以使用List< object>保持参考,例如:

   
   private List gotRefs = new List();
   public void MyMethod()
   {
      if (!gotRefs.Contains(txtTextBox1)) {
        txtTextBox1.TextChanged += txtTextBox1_TextChanged;
        gotRefs.Add(txtTextBox1);
      }
   }

答案 2 :(得分:0)

你实际上可以使用黑客。

  • 您可以将文本框设置为您的类的私有,以确保只有您的单个类能够访问该文本框并向其添加处理程序。
private TextBox txtChanging;
  • 然后,在您的班级中,您可以创建自定义事件,如textBoxTextChanged
public event Action TextBoxTextChanged;
  • 创建一个标准方法OnTextBoxTextChanged
private OnTextBoxChanged( object sender, EventArgs args )
{
    if( TextBoxTextChanged != null )
        TextBoxTextChanged();
}
  • 将此OnTextBoxChangedMethod绑定到TextBox的TextChanged事件
txtChanging.TextChanged += OnTextBoxChanged;
  • 确保NO OTHER METHOD绑定到文本框的TextChanged事件

  • 将所有主要负载文本更改处理程序绑定到新的自定义事件而不是直接将文本框textchanged事件

TextBoxTextChanged += txtChanged_TextChnaged;
  • 所有文书工作都是因为事件实际上提供了大量信息,但只提供了定义它们的类中的方法

  • 您可以使用

  • 检查绑定的代理人
TextBoxTextChanged.GetInvocationList()

and their count with

TextBoxTextChanged.GetInvocationList().Count() //(C# 4.0/LINQ)

或者只是通过foreach计算它们。