WPF入门(二):初遇RoutedEvent

先做个简单的东西吧,新建个wpf项目,拖动一个menu控件到窗体里。使用设计器添加几个菜单子项,并双击菜单注册事件,代码如下:

 

ExpandedBlockStart.gif 代码
 1  < Window x:Class = " WpfApplication1.WinMain "
 2      xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
 3      xmlns:x = " http://schemas.microsoft.com/winfx/2006/xaml "
 4      Title = " WinMain "  Height = " 494 "  Width = " 715 " >
 5       < Grid >
 6           < Grid.ColumnDefinitions >
 7               < ColumnDefinition Width = " 371* "   />
 8               < ColumnDefinition Width = " 344* "   />
 9           </ Grid.ColumnDefinitions >
10           < Menu Height = " 25 "  Name = " menu1 "  VerticalAlignment = " Top "  Grid.ColumnSpan = " 2 " >
11               < MenuItem Header = " 第一级菜单 "  Click = " MenuItem_Click " >
12                   < MenuItem Header = " 第二级菜单1 "   />
13                   < MenuItem Header = " 第二级菜单2 "   />
14               </ MenuItem >
15           </ Menu >
16       </ Grid >
17  </ Window >
18    
19 
20     ///   <summary>
21       ///  WinMain.xaml 的交互逻辑
22       ///   </summary>
23       public   partial   class  WinMain : Window
24      {
25           public  WinMain()
26          {
27              InitializeComponent();
28          }
29 
30           private   void  MenuItem_Click( object  sender, RoutedEventArgs e)
31          {
32               object  obj  =  e.Source;
33               bool  handled  =  e.Handled;
34 
35              RoutedEvent routedEvent  =  e.RoutedEvent;
36              RoutingStrategy routingStrategy  =  routedEvent.RoutingStrategy;
37 
38 
39              MessageBox.Show( " 触发了事件 \r\n 源: "   +  e.Source.ToString());
40          }
41 
42      }

 

 

 

我们重点看节点Menu和MenuItem,menu是菜单的根节点。header属性是菜单的标题。(顺便说一句,在winform里这些都是设置属性"Text"的,而在wpf里,大多变成"Content"属性)。而让人惊讶的是 “在代码设计器中,我们只能对一级菜单注册事件”,查看代码第11行里。有句“Click="MenuItem_Click"” 熟悉 html人都能明白这个意思,就是注册一个事件,事件名字是“MenuItem_Click”,而事件的实现代码当然是在"CodeBehind"代码后置文件里找了。这里 “二级菜单1”和“二级菜单2”两个菜单的单击都会触发"MenuItem_Click"。也就是说“子控件里的单击 触发了 父控件里注册的事件”。其实是个 “事件路由(RoutedEvent)”,流程如下:

1.先触发子控件的click事件,(本示例没有订阅该事件,等下我们做个订阅尝试)。

2.再触发父控件的click事件。

3.依次再触发该控件的上一级父控件的事件。

这里就有了事件 触发策略问题。即事件如何传递。

 

 我们看下 注册事件的代码 private void MenuItem_Click(object sender, RoutedEventArgs e) ,方法签名里和我们常见的方法签名区别是这个这个参数RoutedEventArgs ,该参数属性有(摘自msdn):

  名称说明
Handled 获取或设置一个值,该值指示路由事件在路由过程中的事件处理当前状态。
OriginalSource 在父类进行任何可能的 Source 调整之前,获取原始报告源(由纯粹命中测试确定)。
RoutedEvent 获取或设置与此 RoutedEventArgs 实例关联的 RoutedEvent
Source 获取或设置对引发事件的对象的引用。

 

我们在事件中,如果想终止该事件的继续传递,设置e.Handled= true就可以了。

 

事件使用的委托的方法签名如下:

 

public delegate void RoutedEventHandler(
	sender,
	RoutedEventArgs e
)
实际上一切都是由RoutedEvent 对象来管理的。也就是说。RoutedEvent处理了事件的传递方式。

名称说明
HandlerType 获取路由事件的处理程序类型。
Name 获取路由事件的标识名称。
OwnerType 获取路由事件的已注册所有者类型。
RoutingStrategy 获取路由事件的路由策略。
public enum RoutingStrategy 路由策略的枚举类型如下:

成员名称说明
Tunnel路由事件使用隧道策略,以便事件实例通过树向下路由(从根到源元素)。
Bubble路由事件使用冒泡策略,以便事件实例通过树向上路由(从事件元素到根)。
Direct路由事件不通过元素树路由,但支持其他路由事件功能,例如类处理、 或 。

 

我们可以设置我们RoutedEvent的传递方式,当然这要自己写控件的时候才用得到。

 

稍候待续...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值