WPF-Input
路由事件
路由事件分为3种:
- bubbling,冒泡事件
- tunneling,隧道事件
- direct,直达事件
冒泡事件
事件触发后从事件源节点一直向上至根节点寻找事件处理器
隧道事件
跟冒泡事件相反,从根节点向下找寻事件处理器,一直到事件源节点
直达事件
只有事件源的事件处理器被调用,没有路由行为
Example
xaml:
<Button PreviewMouseDown="PreviewMouseDownButton" MouseDown="MouseDownButton"> <Grid PreviewMouseDown="PreviewMouseDownGrid" MouseDown="MouseDownGrid"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Canvas PreviewMouseDown="PreviewMouseDownCanvas" MouseDown="MouseDownCanvas" Width="20" Height="18" VerticalAlignment="Center"> <Ellipse PreviewMouseDown="PreviewMouseDownEllipse" MouseDown="MouseDownEllipse" x:Name="myEllipse" Canvas.Left="1" Canvas.Top="1" Width="16" Height="16" Fill="Yellow" Stroke="Black" /> <Ellipse Canvas.Left="4.5" Canvas.Top="5" Width="2.5" Height="3" Fill="Black" /> <Ellipse Canvas.Left="11" Canvas.Top="5" Width="2.5" Height="3" Fill="Black" /> <Path Data="M 5,10 A 3,3 0 0 0 13,10" Stroke="Black" /> </Canvas> <TextBlock Grid.Column="1">Click!</TextBlock> </Grid> </Button>
cs:
void PreviewMouseDownButton(object sender, RoutedEventArgs e) { Debug.WriteLine("PreviewMouseDownButton"); } void MouseDownButton(object sender, RoutedEventArgs e) { Debug.WriteLine("MouseDownButton"); } void PreviewMouseDownGrid(object sender, RoutedEventArgs e) { Debug.WriteLine("PreviewMouseDownGrid"); } void MouseDownGrid(object sender, RoutedEventArgs e) { Debug.WriteLine("MouseDownGrid"); } void PreviewMouseDownCanvas(object sender, RoutedEventArgs e) { Debug.WriteLine("PreviewMouseDownCanvas"); } void MouseDownCanvas(object sender, RoutedEventArgs e) { Debug.WriteLine("MouseDownCanvas"); } void PreviewMouseDownEllipse(object sender, RoutedEventArgs e) { Debug.WriteLine("PreviewMouseDownEllipse"); } void MouseDownEllipse(object sender, RoutedEventArgs e) { Debug.WriteLine("MouseDownEllipse"); }
注意到MouseDownButton方法没有被触发,这是因为对于Button元素,将MouseDown和紧随其后的MouseUp事件合并成了单个Click事件
停止事件路由
在事件处理方法中,将RoutedEventArgs类型的参数e的属性Handled设置为true即可让事件停止传播。
确定事件源
在bubbling和tunneling事件中,事件处理器参数sender总是事件处理器关联的那个类的实例,以上面的程序为例,对于MouseDownGrid方法,sender永远是Grid对象,如果要知道事件触发的源对象,可以通过RoutedEventArgs参数 e的Source属性获取,这在同一个事件处理方法以同一种方式处理不同的事件源的情况下很有用。
鼠标输入
所有从UIElement类派生的UI元素类,都定义了如下的鼠标输入事件:
键盘输入
UIElement派生类所拥有的键盘输入事件:

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南