C# – Handling the double-click event of a user control with many children controls

ceventsnetuser-controlswinforms

I have a user control consisting of many children controls, and I need to handle the user control's double-click event. So I add the event handler but it's never triggered.

The quickest solution I am finding is to iterate through the children controls and subscribe to their double-click events. Is this really the right way to do it? Are there better ways? Thank you.

Best Answer

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
}
Related Topic