トップ回答者
イベント処理の親子関係について。

質問
-
いつも参考にしております。
イベント処理の発生について質問させていただきます。
【環境】
・Visual C# 2008
・.NET Framework 3.5 SP1
【クラス】
1.オリジナルボタンの作成
public partial class ImageButton : Control
protected override void OnMouseEnter()
protected override void OnMouseLeave()
protected override void OnMouseUp()
protected override void OnMouseDown()
上記4つのイベントにより、ボタン画像を変更しています。
2.オリジナルボタンを複数使用(Controls.Add)したUserControlの作成
public partial class ButtonsPanel : UserControl
pribate int m_selectedID;
private void ButtonsPanel_MouseDown()
MouseDown時に、どのボタンが選択されたかを示すボタンIDをメンバ変数に設定する。
3.ButtonsPanel を使用(Controls.Add)したFormの作成
public partial class FormTest : Form
private void FormTest_MouseDown()
【質問】
このとき、ButtonsPanel で「MouseDown」イベントを発生させたとき、
ImageButton 側の「OnMouseDown」が実行され、ButtonsPanel 側の
「ButtonsPanel_MouseDown」は無反応となります。このため、
m_selectedIDが設定できません。
私の理想は、ImageButton のOnMouseDown()で画像変更後、
続けて、ButtonsPanel の「ButtonsPanel_MouseDown()」の処理を
実行することです。
また、将来的にはButtonsPanel はいろいろなFormで使用します。
FormにButtonsPanelを追加して、FormTest_MouseDown時に
m_selectedIDを取得したいと考えています。
※もちろんこのままでは、FormでのMouseDownも無反応です。
一般的にはこの場合、どのような設計・コーディングを行うのでしょうか。
できればMouseUpは使用せずにMouseDownのみでm_selectedIDを
Form側で取得することは可能でしょうか。
何卒、よろしくお願い申し上げます。
回答
-
WinForm では、子コントロールが受け取った入力イベントはそこで完結し、再帰的に親の同じイベントを呼び出すような仕組みは持っていません。Form の子に Panel がいてさらにその子に Button がいたとき、Button 上でマウスボタンを押下しても Panel.MouseDown や Form.MouseDown は発生しません。
// Panel.OnMouseDown の呼び出しによって Panel.MouseDown が発生するように見せかけることはできますが。
Panel.MouseDown は Button の領域以外の Panel 領域を押下したときにのみ発生しますし、Form.MouseDown も同様です。
普通は以下のような構造になるでしょう。
class ButtonPanel : UserControl { private Button button = new Button(); public event EventHandler ButtonDown; public ButtonPanel() { this.InitializeComponent(); this.button.MouseDown += new MouseEventHandler(this.OnButtonDown); } private void OnButtonDown(object sender, MouseEventArgs e) { if (this.ButtonDown != null) this.ButtonDown(this, EventArgs.Empty); } } class Form1 : Form { public Form1() { this.InitializeComponent(); this.buttonPanel.ButtonDown += new EventHandler(this.OnButtonDown); } }
- 回答としてマーク ベースボールマニア2nd 2010年2月13日 10:23
すべての返信
-
ButtonsPanel が、自分に ImageButton を配置するときに、その ImageButton の MouseDown イベントをハンドルして適切な処理をします。
このとき、自分(ButtonsPanel)の OnMouseDown を呼び出すことも考えられますが、どちらかというと ButtonsPanel は ButtonClick イベントなりの独自イベントを用意し、各 ImageButton のクリック時にこのイベントを発生させるのが自然でしょう。
Form の方も、Form 自体の MouseDown ではなく、追加したコントロール(ButtonsPanel)のイベントをハンドルします。 -
-
WinForm では、子コントロールが受け取った入力イベントはそこで完結し、再帰的に親の同じイベントを呼び出すような仕組みは持っていません。Form の子に Panel がいてさらにその子に Button がいたとき、Button 上でマウスボタンを押下しても Panel.MouseDown や Form.MouseDown は発生しません。
// Panel.OnMouseDown の呼び出しによって Panel.MouseDown が発生するように見せかけることはできますが。
Panel.MouseDown は Button の領域以外の Panel 領域を押下したときにのみ発生しますし、Form.MouseDown も同様です。
普通は以下のような構造になるでしょう。
class ButtonPanel : UserControl { private Button button = new Button(); public event EventHandler ButtonDown; public ButtonPanel() { this.InitializeComponent(); this.button.MouseDown += new MouseEventHandler(this.OnButtonDown); } private void OnButtonDown(object sender, MouseEventArgs e) { if (this.ButtonDown != null) this.ButtonDown(this, EventArgs.Empty); } } class Form1 : Form { public Form1() { this.InitializeComponent(); this.buttonPanel.ButtonDown += new EventHandler(this.OnButtonDown); } }
- 回答としてマーク ベースボールマニア2nd 2010年2月13日 10:23