Can anyone raise any RoutedEvent in WPF?

VitalyB picture VitalyB · Feb 3, 2011 · Viewed 8.1k times · Source

In C# events were always very protected: Only the owner of the event could trigger them. However, this seems to be completely different in WPF - Anyone can throw any event at any time. To test that, I've written the code in the bottom.

When I used RaiseEvent to raise Button.Click, the event above caught it. Is that the planned behavior of WPF events? Just letting anyone throw any events they wish? Also, if so, then what is the meaning of the OwnerType when you register the event? I thought it is some kind of protection, yet if it is, it is a poor one since anyone can access the public event and use AddOwner function to add more owners.

Thanks!

XAML

<StackPanel Button.Click="ButtonBase_OnClick">
    <Button Name="RealButton">Real button</Button>
    <WpfWindow:VitalyControl MouseDown="UIElement_OnMouseDown">
      I am almost a button
    </WpfWindow:VitalyControl>
</StackPanel>

Code behind

The custom control:

class VitalyControl : Label
{
    public VitalyControl()
    {
        this.MouseDown += new MouseButtonEventHandler(VitalyControl_MouseDown);
    }

    void VitalyControl_MouseDown(object sender, MouseButtonEventArgs e)
    {
        RaiseEvent(new RoutedEventArgs(Button.ClickEvent, this));
    }
}

And the handler:

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("Button was pressed");
    }

Answer

Steven Jeuris picture Steven Jeuris · Feb 3, 2011

This is by design, and is actually one of the reasons for RoutedEvents. They are called routed events because they are routed across the element tree. The behavior you are experiencing is called 'singular handler attachment point' on msdn. You specify that StackPanel should listen to all Button.Click events.

In your custom control, you raise a button click event. This 'bubbles' up to the stackpanel, which handles it.

UPDATE:

For this routing to work, I assume every UIElement needs to be able to raise any routed event. Routed Events are only used by UI elements, and are an answer to complexities with WinForms implementations. They aren't a replacement for CLR events. The owner type is used internally when resolving an event by name.