0
votes

Refer to this previous question I asked where I couldn't get the click event for a UserControl on my form to fire off.

The way I have my control set up is I have the control itself sized to 50, 20. I then a have panel sized 25, 20 set to dock on the right side. In code within the UserControl itself, anytime the background of the control or the panel that acts as the "switch" are clicked, it fires off this code:

    private void toggleClick(object sender, EventArgs e) {
        if (toggleStatus) { // set to "on"
            this.BackColor = Color.Red;
            this.pnlSwitch.Dock = DockStyle.Left;                
            toggleStatus = false;
        } else { // set to "off"
            this.BackColor = Color.Green;
            this.pnlSwitch.Dock = DockStyle.Right;                
            toggleStatus = true;
        }
    }

This works great and goes off every time. However, I put my UserControl in a form and tried to tie a click event to this method:

    private void toggleSoundClick(object sender, EventArgs e) {
        MessageBox.Show("Test");
    }

When I click on the background of the control, this fires off and everything works like it should. However, if I click on the panel that acts as the "switch", the click event in my form doesn't fire (but the click event in the UserControl itself does, which isn't the issue). I can kind of understand this being something like z-indexing in CSS, but it still baffles me why a click event inside the control wouldn't cause it to fire off.

My question is, how can I get around this type of behavior?

edit I also can't integrate the behavior from the click event inside the form into the click event inside the UserControl. I have several of these controls on my form, and all have different behavior depending on which is clicked.

2
Every control you click should have event to react on click. It's not z-order as alone, it's what window you click (control = window), window doesn't know about anything behind. Yes control have parent, but by default parent is not informed when kid is clicked, you have to implement that. Subscribe all controls of your UserControl, which have to be clicked, to Click event (it can be same event) where you display message.Sinatr
It took me a second to get your answer, but I figured it out, thank you very much.Ben Black

2 Answers

3
votes

After taking Sinatr's suggestion I googled a bit more and found this post on here. What I ended up doing was unsubscribing all click events for the "switch" panel, then putting this code inside my UserControl.

    public new event EventHandler Click {
        add {
            base.Click += value;
            foreach (Control control in Controls) {
                control.Click += value;
            }
        }
        remove {
            base.Click -= value;
            foreach (Control control in Controls) {
                control.Click -= value;
            }
        }
    }

This made it so that when I subscribed the click event for the control itself to the toggleClick method, it also registered it with the "switch" panel (which is why I unregistered all other click events, otherwise it would fire off twice), and it also caused the toggleSoundClick method to be subscribed to the "switch" panel as well when I subscribed it to the control itself inside my form.

edit For my purposes I wanted to add the click events recursively to all controls, no matter the depth, so I changed the code to this

    public new event EventHandler Click {
        add {
            subscribeToEvent(this, value);
        }
        remove {
            unsubscribeFromEvent(this, value);
        }
    }
    private void subscribeToEvent(Control control, EventHandler eventHandler) {
        control.Click += eventHandler;
        foreach (Control child in control.Controls) {
            subscribeToEvent(child, eventHandler);
        }
    }
    private void unsubscribeFromEvent(Control control, EventHandler eventHandler) {
        control.Click -= eventHandler;
        foreach (Control child in control.Controls) {
            unsubscribeFromEvent(child, eventHandler);
        }
    }
0
votes

In the UserControl code that is firing correctly, add

e.Handled = false;

By setting the EventArgs' Handled property to false, the click event is passed through and hopefully caught (again) by the listener in your form method.