惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Vulnerabilities – Threatpost
T
The Blog of Author Tim Ferriss
S
SegmentFault 最新的问题
D
DataBreaches.Net
博客园_首页
罗磊的独立博客
B
Blog
T
Threat Research - Cisco Blogs
C
Cisco Blogs
GbyAI
GbyAI
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
G
GRAHAM CLULEY
H
Help Net Security
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
爱范儿
爱范儿
SecWiki News
SecWiki News
T
Threatpost
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Schneier on Security
Schneier on Security
T
The Exploit Database - CXSecurity.com
Google Online Security Blog
Google Online Security Blog
T
Tor Project blog
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Y
Y Combinator Blog
H
Hacker News: Front Page
V
V2EX
Security Latest
Security Latest
Cloudbric
Cloudbric
Simon Willison's Weblog
Simon Willison's Weblog
Attack and Defense Labs
Attack and Defense Labs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
P
Proofpoint News Feed
博客园 - 三生石上(FineUI控件)
NISL@THU
NISL@THU
S
Secure Thoughts
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
V2EX - 技术
V2EX - 技术
Vercel News
Vercel News
P
Palo Alto Networks Blog
IT之家
IT之家
MyScale Blog
MyScale Blog
有赞技术团队
有赞技术团队
Application and Cybersecurity Blog
Application and Cybersecurity Blog
D
Docker
Google DeepMind News
Google DeepMind News
Webroot Blog
Webroot Blog

博客园 - 赖仪灵

分享几个简单的WPF控件(代码) 捕捉WPF应用程序中XAML代码解析异常 设置WPF窗口相对于非WPF窗口的位置 上海.NET俱乐部--微软社区巡展VSTS上海专题活动 WPF关于WindowInteropHelper的一个BUG WPF全景体验 最优化WPF 3D性能(基于“Tier-2”硬件) Windows Vista桌面窗口管理器(3) 闲话WPF之二六(WPF性能优化点) 闲话WPF之二五(WPF中的ControlTemplate [3]) 闲话WPF之二四(WPF中的ControlTemplate [2]) Windows Vista桌面窗口管理器(2) 闲话WPF之二三(WPF中的ControlTemplate [1]) 闲话WPF之二二(WPF中的Style) Windows Vista桌面窗口管理器(1) 闲话WPF之二一(WPF中的数据处理 [3]) 闲话WPF之十九(WPF中的传递事件 [1] ) 闲话WPF之十八(WPF中的资源 [4] ) 闲话WPF之十七(WPF中的资源 [3])
闲话WPF之二十(WPF中的传递事件 [2] )
赖仪灵 · 2007-01-07 · via 博客园 - 赖仪灵

前一个Post当中介绍了WPF如何处理事件的传递过程。如何定义传递事件,并且对事件进行了分类。现在,我们看看WPF到底是如何处理Bubbling和Tunneling事件的。最后介绍了Attached事件。

在UIElement类,预定义了很多的传递事件,比如键盘、鼠标等等。其中大多数是Bubbling事件,其中很多的事件都还有一个对应的Tunneling事件。所有的Tunneling事件都是Preview前缀命名,它们都在对应的Bubbling事件之前激发。比如PreviewMouseMove这个Tunneling事件是在MouseMove这个Bubbling事件之前激发的。

Tunneling事件的好处就是可以有机会改变或者取消后面的Bubbling事件。WPF内建的响应事件只会对Bubbling事件进行响应,当然,前提了Bubbling和Tunneling同时定义。这种行为有什么好处呢?看下面的一个例子:比如,我们想实现一种特殊的编辑框,只允许输入一些特定的字符。以前的实现方法在处理编辑框的KeyDown或者编辑框的WM_CHAR事件,然后判断新输入的字符是否满足条件,如果不满足,我们再把编辑框的值设置为原来的值。这种实现技术会有字符的一个回退过程。而在WPF中,实现方法不同,直接在PrevewKeyDown等Tunneling事件中处理,如果是不需要的字符,把事件设置为已经处理过。这样这个事件就不会进入到后面的Bubbling事件KeyDown中,WPF也根本不会显式这个字符。这种方法的效果将比之前的回退处理好很多。

虽然我们可以通过RoutedEventArgs参数的Handled属性为True来终止事件的传递。但是,有时候我们需要某个事件始终被接受处理,这可以通过程序代码实现。使用重载的AddHanlder方法。比如,我们给窗口添加一个鼠标右键的处理方法(其中MRBD_Handler是类的一个事件方法):

public AboutDialog()
{
 InitializeComponent();
 this.AddHandler(Window.MouseRightButtonDownEvent,
  new MouseButtonEventHandler(MRBD_Handler), true);
}

这样,任何条件下,MRBD_Handler都可以接收到窗口的鼠标右键事件。即使鼠标右键是点击在窗口中的某个子控件之上。

【Attached事件】

与Attached属性类似,WPF的Element在事件没有定义的情况下也支持Tunneling或者Bubbling事件。比如,我们可以在一个简单的窗口程序中这样指定事件函数:

<Window xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
 xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
 x:Class=”Window1”
 Button.Click=”Button_Click”
 <Button Text="TestButton" Width="50" Height="30">
</Window>

例子中,因为Window本身没有定义Click事件,所以我们必须指定Click事件属性的名称前缀,也就是定义事件的类名。经过这样的定义后,点击在Window中的TestButton,也会激发属性声明的Click事件,调用对应的Button_Click方法。

为什么这样的定义可以通过呢?首先编译时,XAML会看到Button类确实定义了一个Click的.NET事件。在运行时,会直接调用AddHandler把这两个事件依附到Window对应的类当中。所以上面用XAML属性声明的事件代码与下面的程序代码等效:

public Window1
{
 InitializeComponent();
 this.AddHandler(Button.ClickEvent, new RoutedEventHandler(Button_Click));
}