19

I have a Windows form, having a pane, which contains another class, derived from Windows Forms. This is contained as a control within the pane. It contains two buttons within itself.

I'd like the events of the child control to be passed all the way to the parent window. For example, the child window in the pane has a Cancel button, which is supposed to close it. I'd like the parent control, i.e., the main window to close as well, but how can I intercept the button click event of the child control?

I can modify the child control, but only if there is no other way to achieve this in a proper way, I'd rather like to avoid it.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
user1173240
  • 1,455
  • 2
  • 23
  • 50
  • The description you provided for question is different that the title. What do you want exactly? Do you want to raise click event of parent form when you click on child control ? Do you want to close parent form when you click on a button in child control? Or something else? – Reza Aghaei Mar 21 '16 at 11:31
  • The user will click on buttons present on the child control - apart from some events on the child control, some actions need to be taken even by the parent control, but I am not sure is the best way to signal to the parent control and that some event has been triggered on the child. These actions could be general ones such as close all the forms, to more complex ones. But the parent needs to be aware that an event has been triggered on a control belonging to the child control. – user1173240 Mar 21 '16 at 11:42
  • Whilst you can interact with parent form directly from child, It's better to raise some events by child control and subscribe for the events in parent form. – Reza Aghaei Mar 21 '16 at 11:48

1 Answers1

37

While you can interact with parent form directly from child like this.ParentForm.Close(), but it's better to raise some events by child control and subscribe for the events in parent form.

Raise event from Child:

public event EventHandler CloseButtonClicked;
protected virtual void OnCloseButtonClicked(EventArgs e)
{
    CloseButtonClicked?.Invoke(this, e);
}
private void CloseButton_Click(object sender, EventArgs e)
{
    OnCloseButtonClicked(e);
}

Note: To raise the XXXX event, that's enough to invoke the XXXX event delegate; the reason of creating the protected virtual OnXXXX is just to follow the pattern to let the derivers override the method and customize the behavior before/after raising the event.

Subscribe and use event in Parent:

//Subscribe for event using designer or in constructor or form load
this.userControl11.CloseButtonClicked += userControl11_CloseButtonClicked;

//Close the form when you received the notification
private void userControl11_CloseButtonClicked(object sender, EventArgs e)
{
    this.Close();
}

To learn more about events, take a look at:

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Thank you for this. I shall check if it is possible for me to modify the child control. – user1173240 Mar 21 '16 at 13:01
  • Could you describe where i would place the 'this.userControl11.CloseButtonClicked += userControl11_CloseButtonClicked' command? I initially put this in after my Initialize Component command, but it wont catch the event there. – tCoe Apr 26 '18 at 15:19
  • 1
    @tCoe Putting it after InitializeComponent is correct and it should work. Probably the event is not raised at all in the first place because you probably forget to assign `CloseButton_Click` to the `Click` event of the `CloseButton`. – Reza Aghaei Apr 27 '18 at 21:41
  • For a simpler code approach, you can do the following in the child class: `public event EventHandler CloseButtonClicked; private void btnOK_Click( object sender, EventArgs e ) { CloseButtonClicked?.Invoke( this, e ); }` – TheSteelDuck Feb 26 '19 at 09:03
  • 2
    @ClausMøllerJørgensen Thanks for the feedback, Yes we can, Specially for this part `CloseButtonClicked?.Invoke( this, e );` But ... There is a reason for having `OnCloseButtonClicked`. following the standard event pattern of .NET and also giving the developers the opportunity to override the virtual `OnCloseButtonClicked` method. – Reza Aghaei Feb 26 '19 at 09:10
  • Better explained, impossible; this note _Subscribe for event using designer or in constructor or form load_ excels. – Marcelo Scofano Diniz May 04 '21 at 14:38
  • @MarceloScofanoDiniz sorry what do you mean? – William Martens Jan 09 '23 at 09:55
  • 1
    @WilliamMartens, at that comment time, I were not used to the visual studio way of segregate code.cs and code.designer.cs, and more than few occasions I missed the _Subscribe for event using designer_ ... – Marcelo Scofano Diniz Jan 11 '23 at 14:51
  • @MarceloScofanoDiniz okay, no worries ^_^ – William Martens Jan 12 '23 at 09:27