WPF call main parent control in child control with event handler

Below is a simple example of a WPF solutio and explains how to call a parent control’s method in child control click event.

In this case we will be using

1) Main window

2) Parent user control

3) Child user control

Run Visual Studio and create a new project of type WPF (New Project>Installed>Templates>Visual C#>WPF Application)

Give it a name “WpfTestApp”

By default VS will add MainWindow.xaml

Add a new user control of WPF type by righ clicking on project>Add>New Item>User Control(WPF) and give it a name “ParentUserControl”

Add an other user control and give it a name “ChildUserControl”

On ChildUserControl.xaml file add following code

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width=”100″></ColumnDefinition>
            <ColumnDefinition Width=”150″></ColumnDefinition>
            <ColumnDefinition Width=”100″></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height=”50″></RowDefinition>
            <RowDefinition Height=”50″></RowDefinition>
            <RowDefinition Height=”50″></RowDefinition>
            <RowDefinition Height=”50″></RowDefinition>
        </Grid.RowDefinitions>
        <Label x:Name=”lblNumber1″ Content=”Enter first number” Grid.Row=”0″ Grid.Column=”0″ />
        <TextBox  x:Name=”txtNumber1″ Grid.Row=”0″ Grid.Column=”1″ Margin=”0,7,0,24″/>

        <Label x:Name=”lblNumber2″ Content=”Enter second number” Grid.Row=”1″ Grid.Column=”0″ Margin=”0,4,0,42″ Grid.RowSpan=”2″ />
        <TextBox  x:Name=”txtNumber2″ Grid.Row=”1″ Grid.Column=”1″ Margin=”0,10,0,20″/>

        <Button   x:Name=”btnCalculate” Content=”Calculate” Grid.Row=”2″ Grid.Column=”1″ Click=”btnCalculate_Click” Margin=”65,35,0,31″ Grid.RowSpan=”2″ />
    </Grid>

We have added two text boxes with labels and a button to calculate total which has event “btnCalculate_Click”

Now go to code behind file of above user control and add code below

public partial class ChildUserControl : UserControl
    {
        public ChildUserControl()
        {
            InitializeComponent();
        }

        public static readonly RoutedEvent OnClickedBtnCalculate
             = EventManager.RegisterRoutedEvent(“btnCalculate_Click”, RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(ChildUserControl));

        // expose our event
        public event RoutedEventHandler OnClickedBtnCalculate_Clicked
        {
            add { AddHandler(OnClickedBtnCalculate, value); }
            remove { RemoveHandler(OnClickedBtnCalculate, value); }
        }

        private void btnCalculate_Click(object sender, RoutedEventArgs e)
        {
            RaiseEvent(new RoutedEventArgs(OnClickedBtnCalculate));
        }
    }

At this point we have defined our event now we can go to ParentUserControl and doe other work

Add the following code to ParentUserControl.xaml

<local:ChildUserControl x:Name=”childControl” HorizontalAlignment=”Left” Margin=”10,10,0,0″ VerticalAlignment=”Top” Width=”562″/>
        <Label Content=”Total: ” HorizontalAlignment=”Left” FontSize=”18″ FontWeight=”Bold” Margin=”116,215,0,0″ VerticalAlignment=”Top” Width=”64″/>
        <Label  Content=” ” x:Name=”lblTotal”  FontSize=”18″ FontWeight=”Bold”  HorizontalAlignment=”Left” VerticalAlignment=”Top” Margin=”175,215,0,0″  Width=”64″/>

This is a reference to our child user control, lable to display result

On code behind file now we can access our ChildUserControl’s event we defined earlier on i.e.

this.childControl.OnClickedBtnCalculate_Clicked += CalculateTotal;

We need to call this in our constructor

CalculateTotal is the method which will carry on all work.

public void CalculateTotal(object sender, RoutedEventArgs e)
        {
            var num1 =int.Parse(((WpfTestApp.ChildUserControl)(e.OriginalSource)).txtNumber1.Text);
            var num2 = int.Parse(((WpfTestApp.ChildUserControl)(e.OriginalSource)).txtNumber2.Text);

            double total = num1 + num2;

            lblTotal.Content = total;
        }

At this point we have access to data being passed on our child user control and we can use it as seen above.

complete code of this class should look like below

public partial class ParentUserControl : UserControl
    {
        public ParentUserControl()
        {
            InitializeComponent();
            this.childControl.OnClickedBtnCalculate_Clicked += CalculateTotal;
        }

        /// <summary>
        /// Method to return total of two numbers
        /// </summary>
        public void CalculateTotal(object sender, RoutedEventArgs e)
        {
            var num1 =int.Parse(((WpfTestApp.ChildUserControl)(e.OriginalSource)).txtNumber1.Text);
            var num2 = int.Parse(((WpfTestApp.ChildUserControl)(e.OriginalSource)).txtNumber2.Text);

            double total = num1 + num2;

            lblTotal.Content = total;
        }
    }

Now all we got to do is add reference of ParentUserControl to our MainWindow

We can either drag and drop or add reference manually.

<local:ParentUserControl HorizontalAlignment=”Left” Margin=”45,51,0,0″ VerticalAlignment=”Top”/>

Once you run this you will see that you can eneter two numbers (child user control), click button (child user control), calculation and result (both on parent user control)

This was a simple example how to use events when referencing different user controls in WPF.

2 Comments

  1. Luis Novais Reis

    Very good example, congratulations!
    I have a similar but at the same time different need. I have a Fabtab control I downloaded (allow tabs of usercontrols) and I have the MainWindow. At this window I have a method that cannot run at a UserControl so I would like to invoke from one of my UserControls this method.
    I tried to adapt your solution but was unsuccessful !
    In short I want to click a button at one of my 3 UserControls that execute the method at the Main Window. Is it possible?
    Thanks

  2. Luis Novais Reis

    Just to clarify the way FabTab works

    private ObservableCollection _Views = new ObservableCollection();

    switch (counter)
    {
    case (0):
    MainScreen newView = new MainScreen();
    this._Views.Add(newView);
    newView.LabelText = “Flight Plan”;
    break;
    case (1):
    MapaFinal newView1 = new MapaFinal();
    this._Views.Add(newView1);
    newView1.LabelText = “Runawys”;
    break;

    case (2):
    UserControl1 newView3 = new UserControl1();
    this._Views.Add(newView3);
    newView3.LabelText = “TesteAprox”;
    break;

    }

Comments are closed.