How do I grab events from sub-controls on a user-control in a WinForms App?

The best practice would be to expose events on the UserControl that bubble the events up to the parent form. I have gone ahead and put together an example for you. Here is a description of what this example provides.

  • UserControl1
  • Create a UserControl with TextBox1
  • Register a public event on the UserControl called ControlChanged
  • Within the UserControl register an event handler for the TextBox1 TextChangedEvent
  • Within the TextChangeEvent handler function I call the ControlChanged event to bubble to the parent form
  • Form1
  • Drop an instance of UserControl1 on the designer
  • Register an event handler on UserControl1 for MouseLeave and for ControlChanged

Here is a screenshot illustrating that the ControlChanged event that I defined on the UserControl is available through the UX in Visual Studio on the parent Windows form.

Event Handlers for User Control


The best model for this sort of thing will be creating custom events on your user control, and raising them at the appropriate times.

Your scenario is fairly complex, but not unheard of. (I'm actually in a very similar mode on one of my current projects.) The way I approach it is that the user control is responsible for its own validation. I don't use CausesValidation; instead at the appropriate user control point, I perform validation through an override of ValidateChildren(). (This usually happens when the user clicks "Save" or "Next" on the user control, for me.)

Not being familiar with your user control UI, that may not be 100% the right approach for you. However, if you raise custom events (possibly with a custom EventArgs which specifies whether or not to perform validation), you should be able to get where you want to be.


In case someone is still wondering how to simulate event bubbling in WinForm the method Application.AddMessageFilter is a good place to look at.

Using this method you can install your own filter which monitors all messages being posted to the current thread's message queue.

You should be aware that messages being sent (not posted) cannot be handled by this filter. Fourtounatly, most interesting events (like click events) are posted and not sent and therefore can be monitored by this filter


You will need to wire up the events you care about capturing inside your user control, and publish them through some custom event properties on the user control itself. A simple example would be wrapping a button click event:

// CustomControl.cs
// Assumes a Button 'myButton' has been added through the designer

// we need a delegate definition to type our event
public delegate void ButtonClickHandler(object sender, EventArgs e);

// declare the public event that other classes can subscribe to
public event ButtonClickHandler ButtonClickEvent;

// wire up the internal button click event to trigger our custom event
this.myButton.Click += new System.EventHandler(this.myButton_Click);
public void myButton_Click(object sender, EventArgs e)
{
  if (ButtonClickEvent != null)
  {
    ButtonClickEvent(sender, e);
  }
}

Then, in the Form that uses that control, you wire up the event like you would any other:

// CustomForm.cs
// Assumes a CustomControl 'myCustomControl' has been added through the desinger
this.myCustomControl.ButtonClickEvent += new System.EventHandler(this.myCustomControl_ButtonClickEvent);
myCustomControl_ButtonClickEvent(object sender, EventArgs e)
{
  // do something with the newly bubbled event
}