多くの子コントロールで構成されるユーザーコントロールがあり、ユーザーコントロールのダブルクリックイベントを処理する必要があります。そこで、イベントハンドラーを追加しましたが、トリガーされることはありません。
私が見つけた最も簡単な解決策は、子のコントロールを繰り返し処理し、ダブルクリックイベントをサブスクライブすることです。これは本当に正しい方法ですか?より良い方法はありますか?ありがとうございました。
多くの子コントロールで構成されるユーザーコントロールがあり、ユーザーコントロールのダブルクリックイベントを処理する必要があります。そこで、イベントハンドラーを追加しましたが、トリガーされることはありません。
私が見つけた最も簡単な解決策は、子のコントロールを繰り返し処理し、ダブルクリックイベントをサブスクライブすることです。これは本当に正しい方法ですか?より良い方法はありますか?ありがとうございました。
以下は、ユーザーコントロールに追加されている第1レベルの子コントロールに対してのみ機能します。これらの子に後で追加されるコントロールでは機能しません。たとえば、第1レベルのPanel
子コントロールをダブルクリックしても機能しますLabel
が、パネルに追加されたコントロールでは機能しません。
Test.cs
public partial class Test : UserControl
{
public Test()
{
InitializeComponent();
}
protected override void OnControlAdded(ControlEventArgs e)
{
e.Control.DoubleClick += Control_DoubleClick;
base.OnControlAdded(e);
}
void Control_DoubleClick(object sender, EventArgs e)
{
MessageBox.Show("User control clicked");
OnDoubleClick(e);
}
}
Form1.cs
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var test = new Test();
var label = new Label();
label.Text = "test";
test.Controls.Add(label);
Controls.Add(test);
}
}
他のケースに対処するために、コントロール内にコントロールが含まれている場合は、次のコードを使用できます。他の子コントロールを追加する前に、必ずユーザーコントロールをその親コントロールに追加してください。これを行ったら、コントロール階層を下るのと同じ原則に従います。
簡単に言うと、コントロール階層のどこかにコントロールを追加する前に、その親がコントロールコレクションにすでに追加されていることを確認してください。
Test.cs
protected override void OnControlAdded(ControlEventArgs e)
{
e.Control.DoubleClick += Control_DoubleClick;
e.Control.ControlAdded += OnControlAdded; // add this line
base.OnControlAdded(e);
}
// add this method
private void OnControlAdded(object sender, ControlEventArgs e)
{
e.Control.DoubleClick += Control_DoubleClick;
e.Control.ControlAdded += OnControlAdded;
}
Form1.cs
private void Form1_Load(object sender, EventArgs e)
{
var test = new Test();
var panel1 = new Panel();
panel1.BackColor = Color.AliceBlue;
var panel2 = new Panel();
panel2.BackColor = Color.AntiqueWhite;
var label1 = new Label();
label1.Text = "test 1";
label1.BackColor = Color.Aquamarine;
var label2 = new Label();
label2.Text = "test 2";
label2.BackColor = Color.Azure;
// !!! order is important !!!
// first add at least one child control to the test control
// this works as expected
//Controls.Add(test);
//test.Controls.Add(panel1);
//panel1.Controls.Add(panel2);
//panel2.Left = 50;
//panel1.Controls.Add(label1);
//panel2.Controls.Add(label2);
// this works as expected
//test.Controls.Add(panel1);
//Controls.Add(test);
//panel1.Controls.Add(panel2);
//panel2.Left = 50;
//panel1.Controls.Add(label1);
//panel2.Controls.Add(label2);
// this doesn't work for panel2 and it's children
Controls.Add(test);
panel1.Controls.Add(panel2); // panel2 & children will not trigger the events
// all controls added to control collections
// prior to this line will not trigger the event
test.Controls.Add(panel1);
panel2.Left = 50;
panel1.Controls.Add(label1);
panel2.Controls.Add(label2); // will not trigger the event
}
優れたUIを作成するには、(パネル)親コントロールと多くの子コントロール(内)を使用すると便利です。たとえば、多くのラベル(子供)を持つ1つのパネル(親)。
このコードは、MouseEnterイベント(およびその他のイベント)を特定の親コントロールとそのすべての子コントロールに追加する場合に使用します。
パネルやラベルから独自のボタンを作成し、MouseOverなどを処理するための単一のコントロールとしてボタンを処理する場合に最適です。
また、MouseEnterイベント(およびその他のイベント)を他のすべてのコントロールとその子コントロールに追加するコードも追加しました。それが誰かを助けることができることを願っています...
// ------------ WINDOWS FORM'S CLASS ------------------------------------
public partial class WFEvent : Form
{
// ------------ CONSTRUCTOR -----------------------------------------
public WFEvent()
{
// Create Events for Control
CreateEventsControl(pnlParent);
// Create Events for Other Controls
CreateEventsOtherControls(this);
}
// ------------ PRIVATE METHODS -------------------------------------
// Create Events for Parent Control (e.g. a Panel) and Child Controls...
private void CreateEventsControl(Control control)
{
// Create Events for Parent Control
control.MouseEnter += (sender, e) => { CtlMouseEnter(control); };
control.Click += (sender, e) => { CtlClick(control); };
// Create Events for Child Controls...
CreateEventsControlChildControls(control);
}
// Create Events for Parent Control's Child Controls...
private void CreateEventsControlChildControls(Control control)
{
foreach (Control childControl in control.Controls)
{
// Create Events for Parent Panel's Child Control
childControl.MouseEnter += (sender, e) => { CtlMouseEnter(control); };
childControl.Click += (sender, e) => { CtlClick(control); };
// Create Events for Child Control's Child Controls...
CreateEventsControlChildControls(childControl);
}
}
// Create Events for Other Control's Parent and Child Controls...
private void CreateEventsOtherControls(Control control)
{
// Create Event for Other Control's Parent Control
control.MouseEnter += (sender, e) => { CtlOtherMouseEnter(control); };
//control.Click += (sender, e) => { CtlOtherClick(control); };
// Create Event for Other Control's Child Control...
CreateEventsOtherControlsChildControls(control);
}
// Create Event for Other Control's Child Controls...
private void CreateEventsOtherControlsChildControls(Control control)
{
foreach (Control childControl in control.Controls)
{
if (childControl != pnlParent)
{
// Create Events for Other Control's Child Control
childControl.MouseEnter += (sender, e) => { CtlOtherMouseEnter(control); };
//childControl.Click += (sender, e) => { CtlOtherClick(control); };
// Create Events for Other Control's Child Controls's Child Control...
CreateEventsOtherControlsChildControls(childControl);
}
}
}
// MouseEnter for Controls
private void CtlMouseEnter(Control control)
{
Code...
}
// Click for Controls
private void CtlClick(Control control)
{
Code...
}
// MouseEnter for Other Controls
private void CtlOtherMouseEnter(Control control)
{
Code...
}
// Click for Other Controls
//private void CtlOtherClick(Control control)
//{
// Code...
//}
}