在 C# 中,事件总是受到非常严格的保护:只有事件的所有者才能触发它们。然而,这在 WPF 中似乎完全不同——任何人都可以随时抛出任何事件。为了测试这一点,我在底部编写了代码。
当我使用 RaiseEvent 引发 Button.Click 时,上面的事件捕获了它。这是 WPF 事件的计划行为吗?只是让任何人抛出他们想要的任何事件?另外,如果是这样,那么注册事件时 OwnerType 的含义是什么?我认为这是某种保护,但如果是的话,那就太糟糕了,因为任何人都可以访问公共(public)事件并使用 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");
}
最佳答案
这是设计使然,实际上是 RoutedEvents 的原因之一。它们被称为路由事件,因为它们是跨元素树路由的。您遇到的行为在 msdn 上称为“单一处理程序连接点” .您指定 StackPanel 应该监听所有 Button.Click 事件。
在您的自定义控件中,您引发了一个按钮单击事件。这会“冒泡”到处理它的堆栈面板。
更新:
要使此路由正常工作,我假设每个 UIElement 都需要能够引发任何路由事件。路由事件仅由 UI 元素使用,并且是对 WinForms 实现复杂性的回答。它们不能替代 CLR 事件。 所有者类型在内部使用when resolving an event by name .
关于c# - 任何人都可以在 WPF 中引发任何 RoutedEvent 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4888610/