WPF-RoutedEvent和CLR Event.
目录
RoutedEvent(路由事件)和 CLR Event(普通 .NET事件)是两种不同机制的事件系统。
一、CLR Event(普通 .NET 事件)
本质
标准的.NET 事件,基于 delegate(委托) 实现。
public event EventHandler MyEvent;特点
- 只能由 事件源对象本身触发
- 只能由 该对象的订阅者接受
- 不会在元素树种传播
- 是C#语言层面的机制
工作方式
事件源 -> 订阅者例如:
button.Click += Button_Click;这里只是 button 自己触发,只有订阅它的对象能收到。
二、RoutedEvent(WPF路由事件)
本质
是 WPF 在 CLR Event 之上封装的一套 带“传播机制”的事件系统。
它允许事件在 视觉树/逻辑树 中传递。
三种路由策略
| 类型 | 说明 | 传播方向 |
|---|---|---|
| Bubbling(冒泡) | 从子元素往父元素传 | 子 -> 父 |
| Tunneling(隧道) | 从父元素往子元素传 | 父 -> 子 |
| Direct(直达) | 不传播 | 只在源 |
典型例子
Button.Click 是什么?
public static readonly RoutedEvent ClickEvent它是一个 Bubbing RoutedEvent
当你点击 Button:
Button
↓
StackPanel
↓
Grid
↓
Window父级控件都可以收到这个 Click 事件。
三、核心区别对比
| 对比项 | CLR Event | RoutedEvent |
|---|---|---|
| 是否传播 | 不传播 | 在元素树中传播 |
| 作用范围 | 单对象 | 整个可视化树 |
| 是否支持事件拦截 | 不支持 | 可以 e.Handled = true |
| 是否支持附加处理器 | 否 | AddHandler |
| 是否支持XAML绑定 | 否 | 支持 |
四、代码对比示例
CLR Event示例
public event EventHandler MyEvent;只能这样用:
obj.MyEvent += Handler;RoutedEvent示例
注册:
public static readonly RoutedEvent MyEvent =
EventManager.RegisterRoutedEvent(
"My",
RoutingStratrgy.Bubble,
typeof(RoutedEventHandler),
typeof(MyControl));触发:
RaiseEvent(new RoutedEventArgs(MyEvent));监听:
AddHandler(MyControl.MyEvent, new RoutedEventHandler(Handler));五、一个非常关键的区别
RoutedEvent 可以被“父控件”处理
例如:
<Grid Button.Click="Grid_Click">
<Button Content="Click Me"/>
</Grid>即使 Button 没写 Click事件,Grid也能收到。
CLR Event 做不到。
六、什么时候用哪个?
用 CLR Event
- 普通业务类
- ViewModel
- 非 UI 逻辑
- 简单对象通信
用 RoutedEvent
- 自定义控件
- 需要父控件统一处理子控件事件
- 控件库开发
- 想利用 WPF 事件路由机制
七、总结
“CLR Event 是 对象级事件”
“RoutedEvent 是 树级传播事件”