WPF新手村教程(三)路由事件如何为?

摘要:WPF个人文档(三)—— 路由事件 一.路由事件 先来说一下分类,参考某位博主以及博主参考的对应资料分类,先留个印象,然后我们逐步讲解 路由事件:冒泡事件、隧道事件(预览事件)、直接事件(直达事件) 事件(从作用角度划分):生命周期事件、输
WPF个人文档(三)—— 路由事件 一.路由事件 先来说一下分类,参考某位博主以及博主参考的对应资料分类,先留个印象,然后我们逐步讲解 路由事件:冒泡事件、隧道事件(预览事件)、直接事件(直达事件) 事件(从作用角度划分):生命周期事件、输入事件(鼠标事件、键盘输入事件、触控事件) 1.路由 —— 在既定结构中,按照规则传播信号的路径 路径 → 静态结构 规则 → 传播策略 信号 → 事件 路由:网络工程术语,指分组从源到目的地时,决定端到端路径的网络范围的进程 路由的本质:信息从哪里来,要往哪里去,经过哪些节点 1.最原始的路由:网络 在互联网里,一个数据包从电脑中发出去,不是直线飞到服务器 它要经过多个路由器,每个路由器根据规则决定“下一跳” 不是简单传递,而是“根据结构和规则决定传播路径” 2.抽象到程序中 当一个事件发生时,它不一定只通知一个对象,它可能沿着某种结构传播 而这整条“传播路径”就是我们所说的路由 # 比如 UI 是一棵树 Window └── Grid  └── Button 当 Button 被点击时,事件可以: 只在 Button 内处理(直达) 往上通知 Grid → Window(冒泡) 或者从 Window 先往下检查(隧道) 2.路由事件 前面我们已经提到过路由事件的分类,现在我们对其进行较为详细的 吐槽 讲解 路由事件:冒泡事件、隧道事件(预览事件)、直接事件(直达事件) 1.🌱冒泡事件 → 由里往外 传播方向:子 → 父 典型例子:MouseDown、KeyDown、Click 使用场景:子控件触发行为,但由父容器统一处理 统一日志 权限判断 容器级行为控制 MVVM 中命令转发 代码示例: // 只要窗口里任何 Button 被点击,Window 都能收到 this.AddHandler(Button.ClickEvent, new RoutedEventHandler(Window_Click)); 优点:解耦 缺点:调试时要小心,可能在半路被 e.Handled = true 截断 2.🌱隧道事件 → 从外往里 传播方向:父 → 子 事件先从 Window 往下走到最底层控件,然后才进入冒泡阶段 即:父级可以“预先审查”事件 典型事件格式:PreviewXXX 比如:PreviewMouseDown、PreviewKeyDown 经典场景:全局快捷键、输入过滤、行为拦截 代码示例: // 行为拦截:子控件接收不到按键 F5 private void Window_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.F5) e.Handled = true; // e.Handled = true 表示这个按键的路由到此结束 // 这个事件已经被处理完了,不需要继续传播 // 1.阻止事件继续沿当前路由传播 // 2.阻止对应的后续阶段执行 } 3.🌱直达事件 → 不传播 传播方向:只在当前控件触发,不向上也不向下 典型例子:MouseEnter、MouseLeave、Loaded [!IMPORTANT] 为什么它只在当前控件触发,不向上不向下? 因为语义上不适合传播 鼠标进入 Button,不等于进入它父 Grid 如果冒泡,会产生逻辑污染 直达事件适合: 局部状态改变 单控件行为 不需要结构参与的逻辑 总结 🌱冒泡事件:我干了件事,要向上级汇报。
阅读全文