目录

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 是 树级传播事件”