DependencyProperty PropertyChangedCallback wiring
Question
I have a user control with a UniformGrid that has a number of Buttons. I want to assign the same handler to each Button's Click event. So, I added the following to the User Control:
public RoutedEventHandler GridButtonClickHandler
{
get { return ( RoutedEventHandler ) GetValue ( GridButtonClickHandlerProperty ); }
set { SetValue ( GridButtonClickHandlerProperty, value ); }
}
public static readonly DependencyProperty GridButtonClickHandlerProperty =
DependencyProperty.Register ( "GridButtonClickHandler", typeof ( RoutedEventHandler ), typeof ( UniformGrid ),
new PropertyMetadata ( GridButtonClickPropertyChanged ) );
private static void GridButtonClickPropertyChanged ( DependencyObject o, DependencyPropertyChangedEventArgs e )
{
( ( UniformGrid ) o ).Children.OfType<Button> ( ).ToList ( ).ForEach ( b => b.Click += ( RoutedEventHandler ) e.NewValue );
}
Then, somewhere where there is a reference to the User Control (numpad in this example), I have this:
numpad.GridButtonClickHandler += btn_clicked;
I have breakpoints at the GridButtonClickHandler set and the GridButtonClickPropertyChanged method; the first hits when the assignment happens, but the second never hits.
See what I am doing wrong?
Solution
You have registered your dependency propery on the UniformGrid
to set a handler to it you need an UniformGrid instance and the following code:
uniformGrid.SetValue(MyUserControl.GridButtonClickHandlerProperty, new RoutedEventHandler(btn_clicked));
If it was not your goal and would like use it : numpad.GridButtonClickHandler += btn_clicked;
where numpad is your usercontrol. Then the owner type should be your user control during the registration:
public static readonly DependencyProperty GridButtonClickHandlerProperty =
DependencyProperty.Register ( "GridButtonClickHandler",
typeof ( RoutedEventHandler ),
typeof ( MyUserControl),
new PropertyMetadata ( GridButtonClickPropertyChanged ) );
OTHER TIPS
You need a routed event, not a dependency property...
public static readonly RoutedEvent GridButtonClickEvent = EventManager.RegisterRoutedEvent("GridButtonClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyUserControl));
public event RoutedEventHandler GridButtonClick
{
add { AddHandler(GridButtonClickEvent, value); }
remove { RemoveHandler(GridButtonClickEvent, value); }
}
And when a button is clicked, raise the event:
private void GridButton_Click(object sender, RoutedEventArgs e)
{
RaiseEvent(new RoutedEventArgs(GridButtonClickEvent, this));
}