路由概念和路由事件 继承链路 RadioButton的事件解析
WPF 中的路由事件 (Routed Events)是专门为树形 UI 结构设计的事件传递机制。在传统的 C# 开发如 WinForms中事件是“点对点”的即谁触发、谁响应而在 WPF 中所有的 UI 控件都是像树枝一样层层嵌套的。路由事件允许一个事件在 UI 树中上下穿梭直到被某个节点处理为止。一、 核心概念为什么需要“路由”假设你的界面结构是这样的Window - Grid - Button - Image。 如果用户点击了最里面的Image传统 C# 事件只会触发 Image 自己的 Click 事件。但实际上用户不仅是点击了图片同时也点击了包含图片的 Button点击了 Grid甚至点击了整个 Window。路由事件的意义就在于它能让这个“点击动作”按照特定的路线自动通知整个家族树上的相关成员而不需要你手动去挨个绑定。二、 路由的三大策略 (Routing Strategies)WPF 的事件路由引擎提供了三种完全不同的“旅行路线”1. 冒泡路由 (Bubbling) —— 【自下而上】路线像水里的泡泡一样从触发事件的最底层元素开始一级一级往上冒直到最顶层的 Window。应用场景绝大多数普通的交互动作如Click、MouseDown、MouseUp。触发顺序Image触发 ➡Button触发 ➡Grid触发 ➡Window触发。2. 隧道路由 (Tunneling) —— 【自上而下】路线像钻隧道一样从最顶层的根节点 (Window) 开始一级一级往下钻直到找到真正触发事件的那个底层元素。命名规范WPF 中所有的隧道事件都严格以Preview开头如PreviewMouseDown、PreviewKeyDown。触发顺序Window触发 ➡Grid触发 ➡Button触发 ➡Image触发。核心作用给上层父容器一个“提前拦截”或“预处理”的机会。3. 直达路由 (Direct) —— 【点对点】路线不冒泡也不钻隧道只有触发事件的元素本身能收到通知行为和传统的 .NET CLR 事件一模一样。应用场景纯粹的局部状态变化如MouseEnter、MouseLeave。因为鼠标进入某个按钮并不代表鼠标也进入了按钮内部包裹的图片这种事件不需要通知父级或子级。三、 核心机制事件的拦截与中断 (e.Handled)当一个事件在树形结构中游走时无论是冒泡还是隧道任何一个节点只要觉得“这个事件我已经处理完毕不需要其他人再插手了”就可以强行踩下刹车。在事件处理函数的参数RoutedEventArgs e中有一个极其重要的布尔属性e.Handled。private void Button_MouseDown(object sender, MouseButtonEventArgs e) { // 1. 执行你的业务逻辑 Console.WriteLine(按钮处理了点击事件); // 2. 踩下刹车告诉 WPF 路由引擎事件到此为止不要再往上冒泡了。 e.Handled true; }继承链路剖析FrameworkElement(框架元素)定义了控件在屏幕上渲染所需的最基础属性比如Width、Height、Margin以及数据绑定上下文 (DataContext)。但它本身不知道什么是“外观”。Control(基础控件)它是所有 UI (User Interface用户界面) 控件的基类。它引入了Template(控件模板) 属性允许控件拥有自定义的“皮肤” (ControlTemplate)。但是并不是所有的控件都有“内容”比如ProgressBar只有进度条没有文字。ContentControl(内容控件)—— 【Content属性的诞生地】微软发现有很多控件都需要在内部装载“一个东西”比如一段文字、一张图片。于是单独抽离出了ContentControl。它定义了极其核心的Content属性类型为System.Object这意味着它不仅能装字符串还能装任何复杂的 UI 元素。ButtonBase(按钮基类)它继承自ContentControl因此顺理成章地拥有了装载内容的Content属性。它专门负责处理鼠标按下、抬起等点击语义并定义了Click路由事件。Button(按钮实体)最终的具体实现类。它拥有了祖先提供的所有能力能设置大小来自FrameworkElement能换皮肤来自Control能装载任意内容来自ContentControl能被点击来自ButtonBase。ContentControl vs ItemsControlWPF 将控件严格分为了两派。只能装一个元素的叫ContentControl如 Button, Window, Label, CheckBox可以装一堆元素的叫ItemsControl如 ListBox, ComboBox, TreeView其核心属性不再是Content而是Items和ItemsSource。WPF内容模型WPF Content Model里面分两大类控件ContentControl 内容控件代表Button Label CheckBox Window拥有Content属性单个对象仅支持一个直接子元素。不能直接写多个标签。Panel面板 布局面板继承自Panel代表Grid StackPanel Canvas DockPanel WrapPanel拥有ChildrenUIElementCollection集合可以放任意数量子控件。RadioButton方法private void RadioButton_Checked(Object sender,RouteEventArgs e)1、sender:是在XAML里写了这个事件绑定的那个控件简单的来讲是谁挂了这个事件谁就是sender。RadioButton CheckedRadioButton_Checked/RadioButton CheckedRadioButton_Checked/两个单选框全部绑定同一个RadioButton_Checked触发的时候sender就是当前点击的这个RadioButton这种简单场景直接写if(sender is RadioButton rb 即可2、e.OriginalSource(原始源WPF是路由事件RoutedEvent控件内部是由很多更小的UI元素拼出来的比如RadioButton里面包含圆形小圆圈TextBlock文字当你点击RadioButton的内部小圆点点击最先发生在“小圆点”这个最底层的元素这个真正被送鼠标点击到的最底层UI对象就是OriginalSource然后事件向上冒泡一路往上跑跑到最外面的RadioButton在跑到GridWindow。OriginSource物理上真正产生这个事件的最原始元素。什么时候sendere.OriginalSource当把事件挂在外层父容器比如StackPanel上面StackPanel CheckedspSex_CheckedRadioButton Content“男”/RadioButton Content女//StackPanel事件不是写在RadioButton身上事件是写在StackPanel(SpSex)上面这是函数里面·sender永远等于StackPanel因为是StackPanel挂载的方法不会变sender拿不到到底里面哪一个RadioButton被点了那我们去哪里找真正触发动作的控件就去读e.OriginalSource!private void spSex_Checked(object sender,RoutedEventArgs e){//sender 这里固定是StackPanel//真正产生事件的控件放在e.OriginalSourceif(e.OriginalSource is RadioButton rb){rb就是被选中的那个单选按钮}}e.Source还有一个属性叫e.Source(不带Original)Source:路由冒泡过程中当前这一跳的源。事件每往上走一层Source就会被修改。OriginalSource从头到尾永远不变保存最开始那一个。总结OriginalSource 出生点一辈子不变Source旅途上当前站冒泡每上一层就更新sender终点站我们给它注册函数的哪一个对象。

相关新闻

SQL Server列存储索引中Delta Store性能影响与治理

SQL Server列存储索引中Delta Store性能影响与治理

1. 为什么“导入数据到Delta Store”是列存储索引性能的隐形开关很多人在SQL Server中建好列存储索引后,第一反应是“查得快了”,接着就急着上线跑报表、做分析。但很快就会发现:同样一个聚合查询,第一次执行慢得像卡住&#xff0…

2026/10/13 10:36:15 阅读更多 →
Odoo Many2one ondelete策略详解:set null、restrict与cascade选型指南

Odoo Many2one ondelete策略详解:set null、restrict与cascade选型指南

1. 从一次数据清理事故说起:为什么ondelete值得单独拎出来讲很多刚接触Odoo ORM的朋友,在定义Many2one字段时,注意力几乎全放在comodel_name和string上,ondelete这个参数往往是顺手一写,甚至直接省略。我见过不少项目里…

2026/10/13 10:36:15 阅读更多 →
模拟器多开网络隔离:Linux命名空间与多实例IP配置指南

模拟器多开网络隔离:Linux命名空间与多实例IP配置指南

这次我们看一个模拟器、云机、安卓手机多开场景里非常实际的需求:能不能做到一个窗口一个实例,各自拥有独立的网络环境和 IP 配置? 先说边界。这个需求在合法场景下,对应的是移动应用测试、网络兼容性验证、自动化回归、协议调试…

2026/10/13 10:35:14 阅读更多 →

最新新闻

IPS入侵防护系统实战指南:精准防御与零误杀部署

IPS入侵防护系统实战指南:精准防御与零误杀部署

1. 项目概述:这不是防火墙的“加强版”,而是网络边界的“主动哨兵” 很多人第一次听说IPS(Intrusion Prevention System,入侵防护系统),下意识会把它当成“更高级的防火墙”——能拦流量、能设规则、还能看…

2026/10/13 11:19:38 阅读更多 →
PostGIS几何创建核心指南:WKT、SRID与环方向实战

PostGIS几何创建核心指南:WKT、SRID与环方向实战

1. 项目概述:为什么几何图形创建是PostGIS真正的“入门门槛”刚接触PostGIS的人,常以为装好扩展、连上数据库、跑通SELECT ST_AsText(geom)就算入门了。我带过不少从QGIS或ArcGIS转过来的同事,他们能熟练画点线面,却在第一次用SQL…

2026/10/13 11:19:38 阅读更多 →
AI逆向智能体实战:一句话自动化定位网络验证逻辑

AI逆向智能体实战:一句话自动化定位网络验证逻辑

1. 从“一句话”到自动化:AI逆向智能体到底在做什么第一次看到“一句话自动破解网络验证”这种说法,我的反应和大多数人一样——要么是标题党,要么是某个特定场景下的取巧。但把最近几款主流大模型在二进制分析任务上的表现拉出来横向对比之后…

2026/10/13 11:19:38 阅读更多 →
LEF/DEF 5.8解析指南:从UNITS、LAYER到MACRO的物理设计文本验证

LEF/DEF 5.8解析指南:从UNITS、LAYER到MACRO的物理设计文本验证

简介:《LEF/DEF 5.8 语言参考》是Cadence于2017年发布的官方英文技术手册,面向集成电路设计工程师、版图设计人员及EDA工具链使用者,系统讲解LEF与DEF两种IC描述语言的语法规则与设计用途,解决工艺库定义、网表交换与物理实现中的…

2026/10/13 11:19:38 阅读更多 →
LeetCode 167双指针详解:C语言实现有序数组两数之和

LeetCode 167双指针详解:C语言实现有序数组两数之和

刷过 LeetCode 的朋友对 167 这道题应该都不陌生,它经常出现在“双指针”专题的第一页,也被很多面试官当成 C 语言基础功的试金石。题目本身描述很简洁——给你一个 下标从 1 开始 的整数数组,数组已经按非递减顺序排好序,让你找…

2026/10/13 11:19:38 阅读更多 →
Beyond Compare绿色免安装版:便携、纯净、可审计的文件比对方案

Beyond Compare绿色免安装版:便携、纯净、可审计的文件比对方案

简介:这是一份面向软件开发者、运维人员及计算机专业学习者的高效文件比对工具资源,解决代码协作、文档审阅、数据同步与版本差异分析等核心问题。资源为Beyond Compare 4.4.6绿色免安装版,无需注册或破解,解压即用,特…

2026/10/13 11:18:36 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →