50

I have a UserControl, and I need to notify the parent page that a button in the UserControl was clicked. How do I raise an event in the UserControl and catch it on the Main page? I tried using static, and many suggested me to go for events.

peterh
  • 11,875
  • 18
  • 85
  • 108

3 Answers3

90

Check out Event Bubbling -- http://msdn.microsoft.com/en-us/library/aa719644%28vs.71%29.aspx

Example:

User Control

public event EventHandler StatusUpdated;

private void FunctionThatRaisesEvent()
{
    //Null check makes sure the main page is attached to the event
    if (this.StatusUpdated != null)
       this.StatusUpdated(this, new EventArgs());
}

Main Page/Form

public void MyApp()
{
     //USERCONTROL = your control with the StatusUpdated event
     this.USERCONTROL.StatusUpdated += new EventHandler(MyEventHandlerFunction_StatusUpdated);
}

public void MyEventHandlerFunction_StatusUpdated(object sender, EventArgs e)
{
         //your code here
}
StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Jemes
  • 2,822
  • 21
  • 22
  • 7
    instead of ` this.USERCONTROL.StatusUpdated += new EventHandler(MyEventHandlerFunction_StatusUpdated);` you can write `USERCONTROL.StatusUpdated += MyEventHandlerFunction_StatusUpdated`. Saves you typing and screen estate, especially when dealing with generic event arg types. – Zebi May 31 '11 at 20:30
  • Cool, I didn't know that. Visual's "TAB" auto-completion adds the full line by default. – Jemes May 31 '11 at 20:42
  • 4
    You can simplify the body of FunctionThatRaisesEvent() to just: `StatusUpdated ?.Invoke(new object(), new EventArgs());` – NickG Sep 07 '16 at 08:49
  • Can I send my own arguments like that? – Somachr Nov 09 '16 at 09:19
  • sender and eventArgs can be set to whatever you'd like and they can be passed through. Instead of "new object()" in the User Control, pass in whatever object you'd like, then just cast it in the Main event handler. – Jemes Nov 10 '16 at 16:46
  • Where is this MyApp() method ? is this called on page_load ? – Dhananjay Jan 31 '17 at 18:59
  • Note that this does *not* actually demonstrate event bubbling: in this example, the main window registers a listener directly on the child. Bubbling automatically sends messages up the visual tree, allowing the parent window to register a single listener on itself. This becomes advantageous when the parent has many descendants that might dispatch that event. The one handler would handle all descendants, would not need to specify its descendants, and would handle child elements added and removed. – Jonathan Lidbeck May 01 '18 at 22:04
7

Just add an event in your control:

public event EventHandler SomethingHappened;

and raise it when you want to notify the parent:

if(SomethingHappened != null) SomethingHappened(this, new EventArgs);

If you need custom EventArgs try EventHandler<T> instead with T beeing a type derived from EventArgs.

Zebi
  • 8,682
  • 1
  • 36
  • 42
1

Or if you are looking for a more decoupled solution you can use a messenger publisher / subscriber model such as MVVM Light Messenger here

Phil Murray
  • 6,396
  • 9
  • 45
  • 95