在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");
}
答案 0 :(得分:3)
这是设计使然,实际上是RoutedEvents的原因之一。它们被称为路由事件,因为它们在元素树中路由。您遇到的行为在msdn上称为“奇异处理程序附加点”。您指定StackPanel应该侦听所有Button.Click事件。
在自定义控件中,您可以引发按钮单击事件。这会“冒泡”到堆栈面板,它会处理它。
更新:
要使此路由生效,我假设每个 UIElement 都需要能够引发任何路由事件。路由事件仅由UI元素使用,并且是WinForms实现的复杂性的答案。它们不是CLR事件的替代品。 所有者类型在内部使用when resolving an event by name。