Reputation: 6135
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
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