I am trying to get routed events working with child controls that will manually fire these events and they will bubble up and be handled at the main grid level. I basically want to do something like this:
<Grid Name="Root" WpfApplication5:SpecialEvent.Tap="Catcher_Tap">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<WpfApplication5:UserControl2 Grid.Row="0" x:Name="Catcher" />
<WpfApplication5:UserControl1 Grid.Row="1" />
<Frame Grid.Row="2" Source="Page1.xaml" />
</Grid>
But when I run my example, I get a null reference in the presentation framework, the application never initializes, it fails when it's trying to load/initialize the XAML (InitializeComponent()). Here's the small file that contains the event:
public class SpecialEvent
{
public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
"Tap", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(UserControl1));
// Provide CLR accessors for the event
public event RoutedEventHandler Tap;
}
I am basically wanting to copy the behavior of how ButtonBase.Click allows parents to subscribe to any button click() methods for their children. But, this doesn't seem to be working for anything but ButtonBase.Click(). That is, when I switch out my custom WpfApplication5:SpecialEvent.Tap="Catcher_Tap"
to ButtonBase.Click="Catcher_Tap"
it works. Any ideas why? What is ButtonBase doing that I'm not doing?
Routed commands give you three main things on top of normal event handling: Routed command source elements (invokers) can be decoupled from command targets (handlers)—they do not need direct references to one another, as they would if they were linked by an event handler.
A routed event is an event registered with the WPF event system, backed by an instance of the RoutedEvent class, and processed by the WPF event system. The RoutedEvent instance, obtained from registration, is typically stored as a public static readonly member of the class that registered it.
The difference between the two, as the naming convention implies, is that a tunneling event will start at the highest node in the tree (probably the Window) and going down to the lowest child. A bubbling event will start at the child and then go upwards again.
After playing around some more, I found that it's possible to accomplish what I needed in the code behind of the main window like so:
public MainWindow()
{
InitializeComponent();
Root.AddHandler(SpecialEvent.TapEvent, new RoutedEventHandler(Catcher_Tap));
}
For some reason, specifying it in the XAML as you would do for ButtonBase() does not work, but adding the Handler
in the code behind does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With