Pass click event of child control to the parent control - c#

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.

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:
Handling and raising events
Standard .NET event pattern

Related

Pass click event of button on child control to the parent control [duplicate]

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.
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:
Handling and raising events
Standard .NET event pattern

.Net Winforms notify all open windows

I am new to .Net Winforms, i generally work on either console apps or MVC.
I am developing a MDI WinForms application, and if I make a change in one (any) window, I need all other open MDI forms to refresh when the change has been made so they can also show the updated data.
How can this be achieved - In my old Delphi (v3) days, you used to "publish" a WM_USER type message and each form would have a "subscriber handler" that would then take the required action but that was a long time ago.
All the forms are slight variations of the data and a change in one form can affect the data in the others..
TYIA
You need an event system between children and parent, which can be accomplished as follows:
Create a base class for your child forms that contains an event to be raised when any data on the form is changed. Let's call it FormChanged event.
Add an event to the Parent form to notify all children. Let's call it ChildFormChanged event.
Upon instantiation of each child form, have the parent form subscribe to the FormChanged event of the child, AND have the new child form subscribe to the ChildFormChanged event of the parent form.
The event handler for the FormChanged event in the parent form is just a pass-through function, that in turn raises the ChildFormChanged event, passing the information received from the child form causing the event to fire.
The ChildFormChanged event can be handled in the base class for child forms via a virtual event handler (to handle generic items) that can be overridden in each child class (to handle specifics of each child form).
I wrote and commented an example app in C# and posted it on Github. Here's the relevant code:
Base child Form:
public event EventHandler<EventArgs> FormChanged;
public virtual void ProcessChange(object sender, EventArgs e)
{
if((sender as Form) != this)
{
//Handle change
}
}
protected void NotifyParent() => FormChanged?.Invoke(this, EventArgs.Empty);
Parent form:
public event EventHandler ChildFormChanged;
public void NotifyAllChildren(object sender, EventArgs e)
=> ChildFormChanged?.Invoke(sender, e);
//Child form creation function
private void createNewFormToolStripMenuItem_Click(object sender, EventArgs e)
{
MDIChildBase newChild = new MDIChild(); //Can be different child forms
newChild.MdiParent = this;
//Parent-child event subscription
newChild.FormChanged += NotifyAllChildren;
ChildFormChanged += newChild.ProcessChange;
newChild.Show();
}
Every child form must call base.NotifyParent(); once any changes occur that you want to propagate to other child forms.
You can still use the windows messaging infrastructure. Explained here and here.

wpf click button in usercontrol calls event in parent window

This must have been asked before, but I am fairly new and don't quite know how to express myself...
1) I have a UserControl that basically acts as a toolbar. I re-use the toolbar in each window, hence the need for a uc.
2) The toolbar is filled with buttons
3) the usercontrol doesn't act on the button (no code), but it should pass the event back to the parent window so the code in the parent window fires up.
How can I do this? Is this a routed event? any sample code in vb.net would be appreciated!
On you user control, you need events that you can fire when the buttons are clicked. Then in your form, you handle the events just like you do for every other control. IE:
public event Button1_ClickedEventHandler Button1_Clicked;
public delegate void Button1_ClickedEventHandler(object sender);
private void Button1_Click(object sender, EventArgs e)
{
if (Button1_Clicked != null) {
Button1_Clicked(this);
}
}
You can call the event whatever you want and pass whatever you want. Here you will notice I am NOT sending the button but THIS, which in this case should be the User Control.

Windows Forms: detect the change of the focused control

I'm implementing copy-paste in a Windows Forms application.
I need to enable/disable the bar-buttons for this two operations when the user changes the focused element in the application.
I can find the current focused control using something like this: http://www.syncfusion.com/FAQ/windowsforms/faq_c41c.aspx#q1021q, but how can I detect that the focused control has changed?
In your form load event handler you could also loop through all of the controls contained in the form and for each focusable control add an event handler for the Enter event:
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control control in Controls)
{
control.Enter += ControlReceivedFocus;
}
}
void ControlReceivedFocus(object sender, EventArgs e)
{
Debug.WriteLine(sender + " received focus.");
}
My proposal is to use Application.Idle event.
Write logic that enables/disables your buttons in Application.Idle event.
Subscribe to Application.Idle event on form shown event
Check button availability on button click (so you never pass accidental click under heavy load)
Do not forget to remove Idle handler on form disposing (or closing), because this is static event
Using this technique you will always have correct buttons state, and you not need to worry about subscribing to many controls events to detect focus change. This is also light-weight approach, because Idle event is raised only when application is not busy.
I think you should add an event handler to the control (or if you have many of the same type, subclass it, and override the appropriate OnChange handler). This way you won't have to 'find' the focused control (it will be given as the sender parameter), and the event will only arise when the change actually happened.
To detect the focus on a control you can create this event:
void MyGotFocus(object sender, EventArgs e)
{
if (sender is TextBox)
{
//TODO YOUR OPERATION
//FOR EXAMPLE
(sender as TextBox).SelectAll();
}
}
and the next step is to associate the control and event by code:
myText1.GotFocus += MyGotFocus;
myText2.GotFocus += MyGotFocus;

How do you determine when a button is clicked in the child on the parent - ASP.NET

In my child user control I have a gridview with an OnRowCommand eventhandler that is executed when Edit button is click. I want to set the visibility of an ASP.NET placeholder control in the parent to true when the Edit button is clicked in child control.
What would be the best way to accomplish this task?
Update:
After a little bit more research on the internets, I create a public event Eventhandler in my child control and rasied the event when the OnRowCommand event was fired. In my page_load event of my parent control, i mapped the child user control event to an private event in my parent control.
Child Control source code:
public event EventHandler MyEvent;
protected void MyGridView_OnRowCommand(object sender, GridViewCommandEventsArgs e)
{
if(MyEvent != null)
MyEvent(sender, e);
}
Parent Control source code:
protected void Page_Load(object sender, EventArgs e)
{
MyChildControl.MyEvent += new EventHandler(this.MyLocalEvent);
}
private void MyLocalEvent(object sender, EventArgs e)
{
MyPlaceHolder.Visible = true;
MyUpdatePanel.Update();
}
There are two methods in addition to bubbling the event worth considering:
a. Create a new event in your child user control. Listen to this event in the parent control. Fire this event in the child control.
b. Listen to the gridview event OnRowCommand in the parent control.
Approach a is superior because there is less of the abstraction leaking through. B is quick and dirty, but if this is a one-time-use user control, it will not have a negative impact.
Creating events is fairly easy, many programs include templates for events which mean they only thing you type is the name of the event (e.g. Resharper).
Off the top of my head I would either create a new event within the child user control that would fire off when OnRowCommand fires, or use OnBubbleEvent - I can't remember the exact name but it's something like that.

Categories