2012-04-10 6 views
1

Я создаю пользовательскую кнопку (Winforms Control Library) и имею код ниже, чтобы весь mouseenter был добавлен ко всем элементам управления в моей кнопке. Когда я запускаю его, он вызывает исключение переполнения стека. У меня есть тот же код с Click вместо MouseEnter, и он отлично работает. Вот код:Почему мой код свойства события вызывает исключение переполнения стека?

public new event EventHandler MouseEnter { 
    add 
    { 
     this.MouseEnter += value; 
     foreach (Control i in Controls) 
     { 
      i.MouseEnter += value; 
     } 
    } 
    remove 
    { 
     this.MouseEnter -= value; 
     foreach (Control i in Controls) 
     { 
      i.MouseEnter -= value; 
     } 
    } 
} 

здесь код нажмите:

public new event EventHandler Click { 
    add { 
     this.Click += value; 
     foreach (Control i in Controls) { 
      i.Click += value; 
     } 
    } 
    remove { 
     this.Click -= value; 
     foreach (Control i in Controls) { 
      i.Click -= value; 
     } 
    } 
} 

ответ

0

В итоге я заменил это. Нажмите на базу. Нажмите.

public new event EventHandler Click { 
     add { 
      base.Click += value; 
      foreach (Control i in Controls) { 
       i.Click += value; 
      } 
     } 
     remove { 
      base.Click -= value; 
      foreach (Control i in Controls) { 
       i.Click -= value; 
      } 
     } 
    } 
+1

Это работает, только если вы только поднимаете базовую версию 'Click'; ваша версия 'Click' стала не чем иным, как * вспомогательным методом для распространения подписки обработчика на дочерние элементы элемента управления. * ** Пожалуйста, не скрывайте эту логику за сумматором событий, просто сделайте четко названный и прокомментированный вспомогательный метод . ** – dlev

5

+= является сокращением для «вызова сумматор для этого события.» Вы вызываете += из своего сумматора. Таким образом, у вас есть несвязанная рекурсия, приводящая к переполнению стека.

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

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

И, наконец, эта функциональность, вероятно, не нужна: в любом случае многие события будут всплывать от детей к родителям.

+0

Я знаю, но почему мой код клика работает, его же, кроме MouseEnter, заменяется на Click, когда этот не работает? – Oztaco

+0

Yup код this.MouseEnter + = значение; вызывает добавление еще одного обработчика событий в MouseEnter. Причина, по которой вы получаете переполнение стека быстрее, чем на клике, заключается в том, что для каждого движения мыши этот код называется –

+0

@ leaf68 Можете ли вы вставить код для события 'Click'? Это довольно странно. – dlev

0

Я думаю, что вы хотели что-то вроде этого (не уверен, если его право на частный член):

private EventHandler mouseEnter; 
public new event EventHandler MouseEnter { 
add 
{ 
    this.mouseEnter += value; 
    foreach (Control i in Controls) 
    { 
     i.mouseEnter += value; 
    } 
} 
remove 
{ 
    this.mouseEnter -= value; 
    foreach (Control i in Controls) 
    { 
     i.mouseEnter -= value; 
    } 
} 

}

Вы this.MouseEnter называющая себя в рекурсии.

Смежные вопросы