3

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");
    }
VitalyB
  • 12,397
  • 9
  • 72
  • 94
  • The OwnerType is more for design tools like Blend and VS, and for debugging too. If you have an instance of a RoutedEvent object, you want to be able to tell which routed event it is, which includes knowing which type the routed event belongs to. – Joe White Feb 03 '11 at 18:46
  • @Joe White: So anyone can throw any event in WPF? Why is there such a leap from C# where nobody (not even derived classes) can trigger events of someone else, whether in WPF everyone can? – VitalyB Feb 04 '11 at 13:53
  • 1
    I hadn't thought about it before, but apparently so. A lot of stuff in WPF is a result of feedback and problems people had with WinForms, so I assume they made this change on purpose. And @Steven Jeuris' answer points out that it would have been difficult to make them super-private like in the past, since they can pass through unrelated classes. – Joe White Feb 06 '11 at 09:47

1 Answers1

3

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.

Steven Jeuris
  • 18,274
  • 9
  • 70
  • 161
  • Hi Steven, I understand the bubbling. I am more confused about the ability of control that has no connection at all to Button to raise a Click event. I'd think that only the owner of the event should be able to do so. – VitalyB Feb 04 '11 at 13:51
  • I'm **guessing** the reason for this is since for UIElement to be able to route received events up the element tree, it probably needs to be able to raise any possible routed event. In order to interpret the events, they need to be public. It might be possible to encapsulate this better, but I don't believe there is any big gain in this. Routed Events are only used by UI elements. Routed events aren't a replacement for CLR events. They simply simplify events for UI's. – Steven Jeuris Feb 04 '11 at 21:33
  • So to summarize :) - Any object can indeed raise any event and any object can catch any event. The owner type isn't designed to protect the encapsulation of the event and its aim is something completely different. – VitalyB Feb 06 '11 at 10:27