Raising an event on parent window from a user control in .NET C#

user246392 picture user246392 · Jun 18, 2010 · Viewed 19.3k times · Source

The title pretty much explains the question. I have a user control loaded into the main window when the application is first run. What I want to do is to raise an event on parent window when a button on the user control is clicked, so how can I raise a parent event from button1_Click on the user control?

Answer

John Kocktoasten picture John Kocktoasten · Aug 7, 2013

This issue seems to not be fully described end-to-end anywhere: The link supplied above is not a complete explanation of how to define, raise, and catch an event from a UserControl to a parent window. It might be obvious to some, but took me a minute to connect the dots, so I'll share my findings. Yes, the way to do this is via a Custom RoutedEvent set to RoutingStrategy.Bubble, but there is more to the story.


In this example, I have a UserControl, named ServerConfigs that has a Save Button. When the user clicks the Save button, I want a button on the parent Window, which contains the UserControl to enable another button, button is called btn_synchronize.

On the UserControl code behind define the following, as per the above RoutedEvent link cited above.

public partial class ServerConfigs : UserControl
{

    // Create RoutedEvent
    // This creates a static property on the UserControl, SettingsConfirmedEvent, which 
    // will be used by the Window, or any control up the Visual Tree, that wants to 
    // handle the event. This is the Custom Routed Event for more info on the 
    // RegisterRoutedEvent method
    // https://msdn.microsoft.com/en-us/library/ms597876(v=vs.100).aspx

    public static readonly RoutedEvent SettingConfirmedEvent =
        EventManager.RegisterRoutedEvent("SettingConfirmedEvent", RoutingStrategy.Bubble,
        typeof(RoutedEventHandler), typeof(ServerConfigs));

    // Create RoutedEventHandler
    // This adds the Custom Routed Event to the WPF Event System and allows it to be 
    // accessed as a property from within xaml if you so desire

    public event RoutedEventHandler SettingConfirmed
    {
        add { AddHandler(SettingConfirmedEvent, value); }
        remove { RemoveHandler(SettingConfirmedEvent, value); }
    }
    ....

    // When the Save button on the User Control is clicked, use RaiseEvent to fire the 
    // Custom Routed Event

    private void btnSave_Click(object sender, RoutedEventArgs e)
    {
    ....
        // Raise the custom routed event, this fires the event from the UserControl
        RaiseEvent(new RoutedEventArgs(ServerConfigs.SettingConfirmedEvent));
    ....
    }
}

There is the implementation example, where the above tutorial ends. So how does one catch the event on the window and handle it?

From the window.xaml, this is how the Custom RoutedEventHandler defined in the user control can be used. This is exactly like button.click etc.

<Window>
....
<uc1:ServerConfigs SettingConfirmed="Window_UserControl_SettingConfirmedEventHandlerMethod" 
                   x:Name="ucServerConfigs" ></uc1:ServerConfigs>
...
</Window>

OR in Window code behind, you can set the EventHandler via AddHandler, usually in the constructor:

public Window()
{
    InitializeComponent();
    // Register the Bubble Event Handler 
    AddHandler(ServerConfigs.SettingConfirmedEvent, 
        new RoutedEventHandler(Window_UserControl_SettingConfirmedEventHandlerMethod));
}

private void Window_UserControl_SettingConfirmedEventHandlerMethod(object sender,
              RoutedEventArgs e)
{
    btn_synchronize.IsEnabled = true;
}