Robert E. McIntosh
Robert E. McIntosh

Reputation: 6135

Get UserControl on Click Event

I created a custom control which contains panels, labels and pictureboxes. I am trying to get get the user controls name property when its clicked event is called.

In my user control, I have the following code to bubble up the click event so any of the children controls can trigger the click event

    private void reclusiveControlLoop(ControlCollection Controls, EventHandler EventValue, Boolean Mode)
    {
        foreach (Control control in Controls)
        {
            if (control.Controls.Count > 0)
            {
                reclusiveControlLoop(control.Controls, EventValue, Mode);
            }

            if (Mode)
            {
                control.Click += EventValue;
            }
            else
            {
                control.Click -= EventValue;
            }
        }
    }

    public new event EventHandler Click
    {
        add
        {
            base.Click += value;
            reclusiveControlLoop(pnlContent.Controls, value, true);
        }
        remove
        {
            base.Click -= value;
            reclusiveControlLoop(pnlContent.Controls, value, false);
        }
    }

The on the form which has the user control I added the following code

Private Sub ListLinkLaunch_Click(sender As Object, e As EventArgs) Handles llCommissions.Click
        Try
            Dim llItem As Control = CType(sender, Control)
            Dim sName As String = llItem.Name.ToString()

            MessageBox.Show(sName)

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

The problem is it isn't returning the name of the control I added which is llCommissions but instead returning the name of the label of the user control lblListLinkTitle.

Upvotes: 0

Views: 65

Answers (1)

JayV
JayV

Reputation: 3271

The reason why you are getting the controls name (lblListLinkTitle for example), is related to how you are assigning the Click event to each of the controls. As your code stands, each control is raising the Click event all the way up to the containing form.

To get your desired behaviour, each control should be raising their Click events to your custom control, and from there, raise a new event to the containing form.

In order to get it to work as you want, make these changes:

Inside the UserControl.cs - Constructor after the call to InitializeComponent

pnlContent.Click += AllControls_Click;
reclusiveControlLoop(pnlContent.Controls, true);

And, this is the rest of your code modified to work slightly differently.

private void AllControls_Click(object sender, EventArgs e)
{
    base.OnClick(e);
}

private void reclusiveControlLoop(ControlCollection Controls, Boolean Mode)
{
    foreach (Control control in Controls)
    {
        if(control.Controls.Count > 0)
        {
            reclusiveControlLoop(control.Controls, Mode);
        }

        if(Mode)
        {
            control.Click += AllControls_Click;
        }
        else
        {
            control.Click -= AllControls_Click;
        }
    }
}

With this method you no longer need to define the new Click EventHandler (public new event EventHandler Click)

What this means in practice is that on your Form, you will never know which control (Label or PictureBox) has been clicked, and that is how it should be, those details should not be passed to the root form.

Upvotes: 1

Related Questions