事件沿着可视化树(Visual Tree)传播,而不是仅限于触发事件的对象本身。有以下几种类型
冒泡(Bubbling) :事件从触发源(如按钮)向上传播到父级容器(如窗口)。
隧道(Tunneling) :事件从根容器向下传播到触发源。
直接(Direct) :类似于传统事件,仅在触发源上处理。
注册事件
// 1. 定义路由事件参数类
// 2. 注册路由事件
// 2.2 定义路由事件附加静态辅助方法, 这样才能在 XAML 中使用
// 3. 触发路由事件
// 4 使用代码或是 xaml 中定义事件处理函数
// 1. 定义路由事件参数类
public class ReportTimeRoutedEventArgs(RoutedEvent routedEvent, object source) : RoutedEventArgs(routedEvent, source)
{
public DateTime ReportTime { get; set; }
}
// 2. 注册路由事件
public static readonly RoutedEvent ReportTimeEvent = EventManager.RegisterRoutedEvent("ReportTime", RoutingStrategy.Bubble,
typeof(EventHandler<ReportTimeRoutedEventArgs>), typeof(ReportTimeButton));
// 2.1 定义路由事件属性,兼容 CRL 的事件处理方式
public event EventHandler<ReportTimeRoutedEventArgs> ReportTime
{
add => this.AddHandler(ReportTimeEvent, value);
remove => this.RemoveHandler(ReportTimeEvent, value);
}
// 2.2 定义路由事件附加辅助方法, 这样才能在 XAML 中使用
public static void AddReportTimeHandler(DependencyObject d, RoutedEventHandler handler)
{
if (d is UIElement uiElement)
{
uiElement.AddHandler(ReportTimeEvent, handler);
}
}
// 2.2 定义路由事件附加辅助方法, 这样才能在 XAML 中使用
public static void RemoveReportTimeHandler(DependencyObject d, RoutedEventHandler handler)
{
if (d is UIElement uiElement)
{
uiElement.RemoveHandler(ReportTimeEvent, handler);
}
}
订阅事件
// 4.1 订阅路由事件
this.AddHandler(ReportTimeButton.ReportTimeEvent, new RoutedEventHandler(this.ReportTimeButton_ReportTime));
<!-- 4.2 xaml 中订阅事件 -->
<Grid Margin="24" routedEventDemo:ReportTimeButton.ReportTime="ReportTimeButton_OnReportTime">
引发事件
// 3. 触发路由事件
this.RaiseEvent(new ReportTimeRoutedEventArgs(ReportTimeEvent, this) { ReportTime = DateTime.Now });
// 3. 触发路由事件
uiElement.RaiseEvent(new ReportTimeRoutedEventArgs(ReportTimeButton.ReportTimeEvent, uiElement) { ReportTime = DateTime.Now });
附加事件
事件引发函数 RaiseEvent 定义在 UIElement 中,如果非 UIElement 类需要事件的话,可以在类中定义事件,只是引发由三方 UIElement 控件引发
// 这里使用 RoutedPropertyChangedEventHandler
public static readonly RoutedEvent ColorChangedEvent = EventManager.RegisterRoutedEvent(nameof(ColorChanged), outingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<Color>), typeof(ColorPickerControl));
// CLR 事件
public event RoutedPropertyChangedEventHandler<Color> ColorChanged
{
add => this.AddHandler(ColorChangedEvent, value);
remove => this.RemoveHandler(ColorChangedEvent, value);
}
// 为了 xaml 中自动提示
public static void AddColorChangedHandler(DependencyObject d, RoutedEventHandler handler)
{
if (d is UIElement uiElement)
{
uiElement.AddHandler(ColorChangedEvent, handler);
}
}
// 为了 xaml 中自动提示
public static void RemoveColorChangedHandler(DependencyObject d, RoutedEventHandler handler)
{
if (d is UIElement uiElement)
{
uiElement.RemoveHandler(ColorChangedEvent, handler);
}
}
// 引发事件
public static void OnColorChanged(UiElement element, Color lastColor, Color newColor)
{
var eventArgs = new RoutedPropertyChangedEventArgs<Color>(lastColor, newColor, ColorChangedEvent)
{
Source = this,
};
element.RaiseEvent(eventArgs);
}