任何人都可以在WPF中提出任何RoutedEvent吗?

时间:2011-02-03 16:15:01

标签: c# .net wpf routed-events

在C#中,事件始终受到非常保护:只有事件的所有者才能触发它们。但是,这在WPF中似乎完全不同 - 任何人都可以随时抛出任何事件。为了测试它,我把代码写在底部。

当我使用RaiseEvent引发Button.Click时,上面的事件就抓住了它。这是WPF活动的计划行为吗?只是让任何人抛出他们想要的任何事件?此外,如果是这样,那么当您注册活动时,OwnerType的含义是什么?我认为它是某种保护,但如果它是,它是一个很糟糕的保护,因为任何人都可以访问公共事件并使用AddOwner功能来添加更多的所有者。

谢谢!

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>

代码

自定义控件:

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

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

处理程序:

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

1 个答案:

答案 0 :(得分:3)

这是设计使然,实际上是RoutedEvents的原因之一。它们被称为路由事件,因为它们在元素树中路由。您遇到的行为在msdn上称为“奇异处理程序附加点”。您指定StackPanel应该侦听所有Button.Click事件。

在自定义控件中,您可以引发按钮单击事件。这会“冒泡”到堆栈面板,它会处理它。

更新:

要使此路由生效,我假设每个 UIElement 都需要能够引发任何路由事件。路由事件仅由UI元素使用,并且是WinForms实现的复杂性的答案。它们不是CLR事件的替代品。 所有者类型在内部使用when resolving an event by name