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

发布于 2024-10-09 09:49:30 字数 96 浏览 0 评论 0原文

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

I would like to know if I bind the TextChanged event handler to a TextBox control, then how can I ensure that won't be allowed to bind this event handler again?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

请持续率性 2024-10-16 09:49:30

您无法确保这一点。理论上,您可以多次将同一事件处理程序绑定到文本框(或其他控件)。事件允许您做的唯一事情是添加处理程序和删除处理程序 - 没有提供其他方法来检查现有订阅者。如果您不相信我,Jon Skeet 在此处和中提供了权威答案 他关于事件的文章

如果您需要确保不会意外地将控件订阅同一事件两次,则需要自己对其进行跟踪。老实说,您永远不应该陷入不知道订阅了哪些事件处理程序的情况。这不仅反映了草率的设计,而且可能还意味着您在不再需要事件处理程序时没有注意删除它们。

此问题的答案中提供了可能的解决方案< /a>,但我警告你不要盲目使用这样的东西。正如其他人所说,这段代码是一种反模式。

You can't ensure that. You would theoretically be allowed to bind the same event handler to a textbox (or other control) more than once. The only thing that events allow you to do is add a handler and remove a handler—there's no additional means provided to check for existing subscribers. If you don't believe me, Jon Skeet provides the authoritative answer here, and in his article on events.

If you need to ensure that you don't accidentally subscribe a control to the same event twice, you'll need to keep track of it yourself. Honestly, you should never end up in a situation where you don't know what event handlers are subscribed. Not only does this reflect sloppy design, but it probably also means that you aren't taking care to remove your event handlers when they are no longer necessary.

A possible solution is provided in the answers to this question, but I caution you from using something like this blindly. As others have argued, this code is something of an anti-pattern.

听风吹 2024-10-16 09:49:30

您可以根据需要以编程方式绑定它多次。如果你想防止这种情况,你可以使用 List保留引用,例如:

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

You can bind it programatically as many times as you'd like. If you want to prevent this you can use a List<object> to keep references in, for example:

   
   private List gotRefs = new List();
   public void MyMethod()
   {
      if (!gotRefs.Contains(txtTextBox1)) {
        txtTextBox1.TextChanged += txtTextBox1_TextChanged;
        gotRefs.Add(txtTextBox1);
      }
   }
安穩 2024-10-16 09:49:30

实际上你可以使用 hack。

  • 您可以将文本框设为您的类的私有,以确保只有您的单个类才能访问该文本框并向其添加处理程序。
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;
  • 确保没有其他方法绑定到文本框的 TextChanged 事件

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

TextBoxTextChanged += txtChanged_TextChnaged;
  • 所有这些文书工作是因为事件实际上提供了大量信息,但仅限于定义它们的类内部的方法

  • 您可以使用检查绑定委托

TextBoxTextChanged.GetInvocationList()

及其计数

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

,或者仅通过 foreach 进行计数。

You can actually use a hack.

  • You can make textbox private to your class to ensure, that only your single class is able to access the text box and add handlers to it.
private TextBox txtChanging;
  • Then, in your class, you can create a custom event like textBoxTextChanged
public event Action TextBoxTextChanged;
  • Create a standart method OnTextBoxTextChanged
private OnTextBoxChanged( object sender, EventArgs args )
{
    if( TextBoxTextChanged != null )
        TextBoxTextChanged();
}
  • Bind this OnTextBoxChangedMethod to TextChanged event of the TextBox
txtChanging.TextChanged += OnTextBoxChanged;
  • Ensure that NO OTHER METHOD is bound to TextChanged event of the text box

  • Bound all your main payload text changed handlers to your new custom event instead of text box textchanged event directly

TextBoxTextChanged += txtChanged_TextChnaged;
  • All that paperwork is because events actually provide a lot of information, but only to the methods inside the class where they are defined.

  • You can check bound delegates with

TextBoxTextChanged.GetInvocationList()

and their count with

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

or just count them through foreach.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文