Можно ли подписать один элемент управления на один и тот же обработчик событий несколько раз? - PullRequest
0 голосов
/ 29 декабря 2010

Я хотел бы знать, если я связываю обработчик событий TextChanged с элементом управления TextBox, то как я могу гарантировать, что не будет разрешено связывать этот обработчик событий снова?

Ответы [ 3 ]

3 голосов
/ 29 декабря 2010

Вы не можете гарантировать, что. Теоретически вам будет разрешено связывать один и тот же обработчик событий с текстовым полем (или другим элементом управления) более одного раза.Единственное, что позволяют вам события, - это добавить обработчик и удалить обработчик - нет дополнительных средств для проверки существующих подписчиков.Если вы мне не верите, Джон Скит дает авторитетный ответ здесь, а в свою статью о событиях .

Если вам нужно убедиться, что вы неЕсли вы случайно подписываете элемент управления на одно и то же событие дважды, вам нужно будет отслеживать его самостоятельно.Честно говоря, вам никогда не следует попадать в ситуацию, когда вы не знаете, какие обработчики событий подписаны.Это не только отражает небрежный дизайн, но, вероятно, также означает, что вы не заботитесь о удалении ваших обработчиков событий, когда они больше не нужны.

Возможное решение представлено вответы на этот вопрос , но я предостерегаю вас от использования чего-то подобного вслепую.Как утверждают другие, этот код является чем-то вроде анти-паттерна.

0 голосов
/ 29 декабря 2010

На самом деле вы можете использовать хак.

  • Вы можете сделать текстовое поле приватным для своего класса, чтобы гарантировать, что только ваш единственный класс сможет получить доступ к текстовому полю и добавить к нему обработчики.
private TextBox txtChanging;
  • Затем в своем классе вы можете создать пользовательское событие, например textBoxTextChanged
public event Action TextBoxTextChanged;
  • Создать стандартный метод OnTextBoxTextChanged
private OnTextBoxChanged( object sender, EventArgs args )
{
    if( TextBoxTextChanged != null )
        TextBoxTextChanged();
}
  • Привязать этот OnTextBoxChangedMethod к TextChanged события TextBox
txtChanging.TextChanged += OnTextBoxChanged;
  • Убедитесь, что НИКАКОЙ ДРУГОЙ МЕТОД не связан с TextChangedсобытие текстового поля

  • Привязать все текстовые измененные обработчики основной полезной нагрузки к новому настраиваемому событию вместо текстового события непосредственно в текстовом поле

TextBoxTextChanged += txtChanged_TextChnaged;
  • Все эти документы связаны с тем, что события на самом деле предоставляют много информации, но только для методов внутри класса, в котором они определены .

  • Вы можете проверить связанных делегатов с помощью

<code>TextBoxTextChanged.GetInvocationList()

и их счет с помощью

TextBoxTextChanged.GetInvocationList().Count() //(C# 4.0/LINQ)</code>

или просто считать их через foreach.

0 голосов
/ 29 декабря 2010

Вы можете привязать его программно столько раз, сколько захотите.Если вы хотите предотвратить это, вы можете использовать список для хранения ссылок, например:

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