2012-04-10 11 views
1

私はカスタムボタン(Winformsコントロールライブラリ)を作成しており、すべてのmouseenterがボタンのすべてのコントロールに追加されるように、以下のコードを用意しています。私はそれを実行すると、スタックオーバーフローの例外が発生します。 MouseEnterの代わりにClickと同じコードがあり、正常に動作します。ここでは、コードは次のようになります。ここイベントプロパティコードがスタックオーバーフロー例外を引き起こすのはなぜですか?

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

私はthis.Clickの代わりにbase.Clickを置き換えました。

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

+=はの省略形です「このイベントのための加算器を起動します。」あなたは加算器から+=に電話しています。したがって、スタックオーバーフローを引き起こすアンバウンド再帰があります。

はあなたのコードを見てみると、あなたがコントロールから、しかし、そのすべての子からだけでなくだけでなく、ハンドラを追加および削除するために、加算器を自分で定義していることが表示されます。特定のイベントの購読者は、実際のイベントが発生したときにのみ通知され、イベントが何も知られていない任意の数の出版社によって発生された場合には通知されないという合理的な期待を持っています。あなたがこれを行うヘルパーメソッドを作成したい場合は、ここでメソッドを呼び出す消費者は、彼らがに取得している内容を正確に把握するので

、それはおそらく、より多くの意味になるだろう。同様に、それは起動するために再帰バグを取り除くでしょう。

最後に、この機能はおそらく必要ありません。多くのイベントが子供から親に吹き飛ばされます。

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再帰に自分自身を呼び出す:

+0

なぜ私のクリックコードが機能するのですか?MouseEnterを除いて同じものがClickと置き換えられます。 – Oztaco

+0

コードthis.MouseEnter + = value; は別のイベントハンドラーをMouseEnterに追加します。クリックよりもスタックのオーバーフローが速くなる理由は、マウスが動くたびにこのコードが呼び出されます。 –

+0

@ leaf68 'Click'イベントのコードを貼り付けることができますか?それはかなり奇妙です。 – dlev

0

は、私はあなたが(プライベートメンバーのためにその権利がかどうかわからない)このようなものを望んでいたと思います。

関連する問題