本文转载自微信公众号《CSharp编程百科全书》,作者zls365。转载本文请联系CSharp编程大全公众号。在WPF中,冒泡事件或隧道事件将通过其层间关系传递到可视化树的上层。但是,有些事件在传递给某些控件时会被“终止”(不再响应相应的注册事件),给人一种事件终结者的印象。例如:mousdown事件上的文本框。原因:事件处理到达控件后,其事件对象属性Handled被标记为True。WPF事件引擎在处理控件的相应事件时,如果检测到该属性为True,则不会调用相应的处理程序。即WPF路由事件被标记为已处理后,并不是不在可视化树上传递;相反,事件引擎不再调用此事件的处理程序。如果还想在上层元素中处理相应的事件(上层是相对于事件的传递方向而言),解决方法:1、如果上层控件可以注册相应的事件。即对应控件的Template属性没有被改写。直接上代码:,MouseEventArgse){MessageBox.Show("TextMouseDownevent");e.Handled=false;//让冒泡继续上传}privatevoidGrid_MouseDown(objectsender,MouseEventArgse){MessageBox.Show("GridMouseDownevent");}2.当自定义控件使用模板时,绑定模板事件不生效,此时上述方法不再生效。例如:自定义列表控件模型版本<样式>ScrollViewer控件模板中,ScrollViewer的MouseButtonDown事件处理如下:断点设置将findPrivatevoidMouseLeftButtonDown(objectsender,MouseButtonEventArgse){//e.Handled=false;}解决方法:UIElement.AddHandler方法:为指定的路由事件添加一个路由事件处理程序,并将该处理程序添加到当前元素的处理程序集合中.详情参见:https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.uielement.addhandler?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15。query%3FappId%3DDev15IDEF1%26l%3DZH-CN%26k%3Dk(System.Windows.UIElement.AddHandler);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)%26rd%3Dtrue&view=netframework-4.8大意:由于WPF事件可视化树上有一个元素将事件标记为在传递过程中已处理,事件将不再继续inue在传递的时候响应,(原因:Handled被标记为True)如果你想让后续的元素响应这个方法,可以使用这个方法。所以我们可以在上面的UserControl构造函数中加入如下代码:表示gridMain处理对应的鼠标点击事件publicUserControl(){InitializeComponent();gridMain.AddHandler(MouseLeftButtonDownEvent,newMouseButtonEventHandler(MouseLeftButtonDown),true);}再次断点调试MouseLeftButtonDown,你会发现断点命中了。AddHandler代码的关键点是最后一个true,它告诉WPF引擎相应的元素调用了这个句柄,即使它被标记为Handled=true。但是元素处理完之后,它的上层元素还是不会响应,因为句柄还是标记为processed。可以看出,WPF路由事件被标记为已处理后,并不是没有在可视化树上传递;相反,不会调用处理程序。在上面的例子中,如果你想让UserControl继续响应,情况和1一样,只要将handle标记为false即可。