0

I've created a custom UserControl, it's a button with a grid inside it.

From the Page that contains it, MainPage.xaml, I need to bind a Click event to the UserControl, and the function for the EventHandler must be written outside, in the MainPage (not inside the UserControl).

So, reading through this question, I've created an Event and a EventHandler function that triggers the event. These are inside the UserControl. This are the classes

UserControl.xaml.cs

public class MyButton : UserControl
{
   public event RoutedEventHandler ButtonClicked;

       private void ButtonClickedHandler()
       {
        //Null check makes sure the main page is attached to the event
        if (this.ButtonClicked != null)
            this.ButtonClicked(this, new RoutedEventArgs());
        Debug.WriteLine("ButtonClickedHandler");
       }
   }

MainPage.xaml.cs

private void MyButton_Click(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("MyButton_Click");
        }

        private void MyButton_Loaded(object sender, RoutedEventArgs e)
        {
            (sender as MyButton).ButtonClicked += MyButton_Click;
        }

As you can see, I've placed a couple of Debug.WriteLine, but they don't get triggered, and I don't know what I'm doing wrong.

Community
  • 1
  • 1
riciloma
  • 1,456
  • 2
  • 16
  • 31
  • 1
    Do you ever call `ButtonClickedHandler()`? – TheCodingDamian Aug 10 '16 at 09:40
  • Yip, @zockDoc's right by the look's of things you have forgot to call the `ButtonClickedHandler()`. –  Aug 10 '16 at 09:53
  • Yeah, but what was the point [in the link](http://stackoverflow.com/questions/6192739/how-do-i-raise-an-event-in-a-usercontrol-and-catch-it-in-mainpage) to make it private then? Anyway, `Debug.WriteLine("MyButton_Click");` doesn't get triggered. – riciloma Aug 10 '16 at 10:06

1 Answers1

1

Just having a single method in your code that is never called by anything will not make your program work. You will first have to call the ButtonClickedHandler() method each time your button is clicked.
To do that, just register a method for the click-event of your button in your xaml file.

<Button Content="This Is Your Button" Click="YourButtonClick"/>

And then call the ButtonClickedHandler() method in there:

private void YourButtonClick(object sender, RoutedEventArgs e) {
    ButtonClickedHandler();
}

A simpler way to solve the problem is using an event property:

UserControl.xaml.cs

public Event RoutedEventHandler ButtonClicked 
{
    add {
        ButtonName.Click += value; //use the name of your button here
    }
    remove {
        ButtonName.Click -= value;
    }
}

And then you can simply register to that event in your MainWindow:

private void MyButton_Loaded(object sender, RoutedEventArgs e)
{
    (sender as MyButton).ButtonClicked += MyButton_Click;
}

By the way, I think it is better to register the event in the xaml file where you also create the control:

TheCodingDamian
  • 443
  • 2
  • 12
  • I've edited the UserControl like you said, and now it works! However, I'm still trying to reconstruct the order of the operations. First `MyButton` gets created, and when it loads, an eventHandler called `MyButton_Click` is registered to the ButtonClicked property. The `Button` inside the UserControl (let's call it `ButtonControl`) has a Click property, `YourButtonClick`. This calls `ButtonClickedHandler()`, that adds a new Handler to `ButtonClicked` with `this.ButtonClicked(this, new RoutedEventArgs())`. `MyButton_Click` is now registered. Is this correct? – riciloma Aug 10 '16 at 10:53
  • 1
    Almost. `MyButton_Click` is already registered from the moment you execute this line: `(sender as MyButton).ButtonClicked += MyButton_Click;` However it is only registered to the `ButtonClicked` event, which is not the same as the event that gets fired when the button within is clicked.. The method `YourButtonClick(object sender, RoutedEventArgs e)` on the other Hand is registered to the Button within the control itself. So when the button is clicked, it is executed, calls `ButtonClickedHandler()` which then finally fires the `ButtonClicked` Event, calling the method`MyButton_Click`. – TheCodingDamian Aug 10 '16 at 11:10
  • 1
    An easier way to understand the procedure is placing a breakpoint at the beginning of the program and at the start of `private void YourButtonClick(object sender, RoutedEventArgs e)`. With the F11 key you will then be able to see what exactly happens step by step. – TheCodingDamian Aug 10 '16 at 11:13
  • I see. It's still a bit convoluted though. Isn't there a way to add a click event to the UserControl rather than going through the button within? – riciloma Aug 10 '16 at 11:14
  • 1
    Well, you could also use an event property, I'll edit my answer to show you how. – TheCodingDamian Aug 10 '16 at 11:27