The following will work only for the first level children control which are being added to the user control. It will not work for the controls which are added subsequently to these children. For example, it will work for a double-click on a first level Panel
child control, but not on a Label
which is added to the panel.
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);
}
}
To address the other case, when you have controls contained inside controls, you can use the following code. Be sure to add the user control to it's parent control before adding any other child controls to it. Once you do that, follow the same principle as you go down the control hierarchy.
To put it simpler, before adding a control anywhere in the control hierarchy, make sure that it's parent is already added to a control collection.
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
}
Best Answer
If I am understanding you properly, your GameButton usercontrol will fire the event when clicked on, but not when the label is clicked on -- and you want both. This is because the label (a control) is on top of the background. Therefore, you need to register your label with the click event as well. This can be done manually in the designer or programmatically for each control on the page.
If you want to do EVERY control in the UserControl, put this into the UserControl's OnLoad event and you can use the same click event for every control:
EDIT: The best way is to create the click event handler property in the user control. This way, every time you add/remove a click event to your user control, it adds/removes it to all the controls within the user control automatically.
This is as per another post:
Hope this helps!