Windows Phone中的路由事件-以ListBox控件为例

来源:互联网 发布:nvslp监控软件下载 编辑:程序博客网 时间:2024/05/20 08:44

  今天我们来介绍一下Windows Phone中的路由事件,以ListBox控件为例。

  首先我们来熟悉一下路由事件的概念。

  路由事件是具有更强传播能力的事件,他们可以在元素树中向上冒泡和向下隧道传播,并且沿着传播路径被事件处理程序处理。路由事件经常以冒泡路由事件和隧道路由事件的形式出现,冒泡路由事件是在元素树中向上传播的一种事件,触发事件的源会把事件传递给他的父元素,他的父元素又会将事件继续向上传递,直到传递到元素树的顶端,或者有着特殊的逻辑处理。稍后会给大家详细讲述冒泡路由事件的工作方式。隧道路由事件的工作方式和冒泡路由事件相同,但方向相反。他是在元素树中向下传播的一种事件,触发事件的源的会寻找他的子元素,然后把事件传递给他。隧道路由事件通常比较容易辨认,因为他们都以单词Preview开头。隧道路由事件总是在冒泡路由事件之前被触发。今天我们的重点是冒泡路由事件。

              
  由于是讲Windows phone中的路由事件,那就要讲一下触摸屏设备所特有的事件--触摸事件。在Windows phone中 触摸事件主要有3种,比较简单,分别是ManipulationStarted事件,他是在用户的手指触摸到屏幕时触发的事件。ManipulationDelta事件,他是用户的手指在屏幕上滑动式触发的事件。ManipulationCompleted事件,他是用户的手指离开屏幕时触发的事件。值得注意的是,以上三种触摸事件都是冒泡路由事件。

                


  好,下面让我们来结合程序详细介绍一下Windows phone中的路由事件。

  新建一个Windows Phone应用程序,在内容Grid中添加以下XAML代码。

 

 1 <ListBox  x:Name="listBox" 2                       ManipulationStarted="listBox_ManipulationStarted"  3                       ManipulationCompleted="listBox_ManipulationCompleted" 4                       > 5                 <ListBoxItem x:Name="listBoxItem1" 6                     ManipulationStarted="listBoxItem1_ManipulationStarted"   7                     ManipulationCompleted="listBoxItem1_ManipulationCompleted"> 8                     <TextBlock x:Name="textBlock1" FontSize="30"  9                                    Text="文本一文本一文本一" 10                                    ManipulationStarted="textBlock1_ManipulationStarted" 11                                    ManipulationCompleted ="textBlock1_ManipulationCompleted"/>12                 </ListBoxItem>13                 <ListBoxItem x:Name="listBoxItem2"14                     ManipulationStarted="listBoxItem2_ManipulationStarted"  15                     ManipulationCompleted="listBoxItem2_ManipulationCompleted">16                     <TextBlock x:Name="textBlock2" FontSize="30"17                                    Text="文本二文本二文本二" 18                                    ManipulationStarted="textBlock2_ManipulationStarted" 19                                    ManipulationCompleted="textBlock2_ManipulationCompleted"/>20                 </ListBoxItem>21             </ListBox>

 

  这段代码比较简单,包括一个listbox控件,和两个listboxitem,每个listboxitem的内容也比较简单,就是一行文本,我们给每个控件都分别注册了ManipulationStarted事件和ManipulationCompleted事件。

  这是完成后的手机界面:

          

  接下来,我们添加后台的事件处理程序,上代码。

  首先添加一个名字空间:

1 using System.Diagnostics;

  然后是事件处理程序的代码:

 1 private void listBox_ManipulationStarted(object sender, ManipulationStartedEventArgs e) 2         { 3             Debug.WriteLine("OUT PUT: listBox_ManipulationStarted in {0}", DateTime.Now.ToLongTimeString()); 4         } 5  6         private void listBox_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) 7         { 8             Debug.WriteLine("OUT PUT: listBox_ManipulationCompleted in {0}", DateTime.Now.ToLongTimeString()); 9         }10 11         private void listBoxItem1_ManipulationStarted(object sender, ManipulationStartedEventArgs e)12         {13             Debug.WriteLine("OUT PUT: listBoxItem1_ManipulationStarted in {0}", DateTime.Now.ToLongTimeString());14         }15 16         private void listBoxItem1_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)17         {18             Debug.WriteLine("OUT PUT: listBoxItem1_ManipulationCompleted in {0}", DateTime.Now.ToLongTimeString());19         }20 21         private void textBlock1_ManipulationStarted(object sender, ManipulationStartedEventArgs e)22         {23             Debug.WriteLine("OUT PUT: textBlock1_ManipulationStarted in {0}", DateTime.Now.ToLongTimeString());24         }25 26         private void textBlock1_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)27         {28             Debug.WriteLine("OUT PUT: textBlock1_ManipulationCompleted in {0}", DateTime.Now.ToLongTimeString());29         }30 31         private void listBoxItem2_ManipulationStarted(object sender, ManipulationStartedEventArgs e)32         {33             Debug.WriteLine("OUT PUT: listBoxItem2_ManipulationStarted in {0}", DateTime.Now.ToLongTimeString());34         }35 36         private void listBoxItem2_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)37         {38             Debug.WriteLine("OUT PUT: listBoxItem2_ManipulationCompleted in {0}", DateTime.Now.ToLongTimeString());39         }40 41         private void textBlock2_ManipulationStarted(object sender, ManipulationStartedEventArgs e)42         {43             Debug.WriteLine("OUT PUT: textBlock2_ManipulationStarted in {0}", DateTime.Now.ToLongTimeString());44         }45 46         private void textBlock2_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)47         {48             Debug.WriteLine("OUT PUT: textBlock2_ManipulationCompleted in {0}", DateTime.Now.ToLongTimeString());49         }

  每个事件处理程序都是类似的,他的功能是在调试时的输出窗口里打印一行文本,这样我们就可以清晰的看到每个事件处理的顺序。

  运行程序,并单击第一个ListBoxItem,我们发现输出窗口会打印一下文字:  

   

 

  我们首先观察前3行文字,他是一个完整的冒泡路由过程,从触发事件的TextBlock,再到ListBoxItem,最后到元素树的顶级元素ListBox终止(其实ListBox并不是真正的顶级元素,真正的顶级元素应该是phone:PhoneApplicationPage控件,但由于没有对phone:PhoneApplicationPage控件的触摸事件进行处理,所以在这里是无法显示的,目前我们姑且认为ListBox控件就是元素树的顶级元素)。我们再来看最后一行文字,比较奇怪,ManipulationCompleted事件并没有完成一个完整的冒泡路由过程,这是怎么回事呢?我们在此留下一个悬念,稍后会给大家解释。

  我们继续完善代码。

  首先在ListBox中添加一个ListBoxItem。

 1 <ListBoxItem x:Name="listBoxItem3" 2                              ManipulationStarted="listBoxItem3_ManipulationStarted" 3                              ManipulationCompleted="listBoxItem3_ManipulationCompleted"> 4                     <CheckBox x:Name="checkBox" 5                              ManipulationStarted="checkBox_ManipulationStarted" 6                              ManipulationCompleted="checkBox_ManipulationCompleted" 7                              > 8                         <TextBlock x:Name="textBlock3" Text="文本三文本三文本三文本三文本三" 9                                    ManipulationStarted="textBlock3_ManipulationStarted"10                                    ManipulationCompleted="textBlock3_ManipulationCompleted"/>11                     </CheckBox>12                 </ListBoxItem>

  这个ListBoxItem的内容是一个CheckBox控件,CheckBox控件中又包含了一行文本。

  这是添加完成后的手机界面。

        

  接下来是事件处理程序的代码。

 1  private void listBoxItem3_ManipulationStarted(object sender, ManipulationStartedEventArgs e) 2         { 3             Debug.WriteLine("OUT PUT: listBoxItem3_ManipulationStarted in {0}", DateTime.Now.ToLongTimeString()); 4         } 5  6         private void listBoxItem3_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) 7         { 8             Debug.WriteLine("OUT PUT: listBoxItem3_ManipulationCompleted in {0}", DateTime.Now.ToLongTimeString()); 9         }10 11         private void checkBox_ManipulationStarted(object sender, ManipulationStartedEventArgs e)12         {13             Debug.WriteLine("OUT PUT: checkBox_ManipulationStarted in {0}", DateTime.Now.ToLongTimeString());14         }15 16         private void checkBox_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)17         {18             Debug.WriteLine("OUT PUT: checkBox_ManipulationCompleted in {0}", DateTime.Now.ToLongTimeString());19         }20 21         private void textBlock3_ManipulationStarted(object sender, ManipulationStartedEventArgs e)22         {23             Debug.WriteLine("OUT PUT: textBlock3_ManipulationStarted in {0}", DateTime.Now.ToLongTimeString());24         }25 26         private void textBlock3_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)27         {28             Debug.WriteLine("OUT PUT: textBlock3_ManipulationCompleted in {0}", DateTime.Now.ToLongTimeString());29             30         }

  和以前也是一样的,也是在调试时的输出窗口里打印一行文本。

  运行程序,并单击新添加的带有CheckBox的ListBoxItem,我们会看到输出窗口会发生变化。  

  

    由于ListBoxItem中包含了一个带有文本的CheckBox控件,所以元素树的层次增加了一层。我们可以清晰的看到,和上一次不一样的是,不论是ManipulationStarted事件还是ManipulationCompleted事件都完成了完整的冒泡路由传递,这又是为什么呢?

  为了进一步解释这个问题,我们进一步完善代码。

  首先给ListBox控件注册一个SelectionChanged事件。

1 <ListBox  x:Name="listBox"2                       ManipulationStarted="listBox_ManipulationStarted" 3                       ManipulationCompleted="listBox_ManipulationCompleted"4                       SelectionChanged="listBox_SelectionChanged" 5                      >

  然后给SelectionChanged事件添加事件处理程序。

1 private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)2         {3             Debug.WriteLine("OUT PUT: listBox_SelectionChanged in {0}", DateTime.Now.ToLongTimeString());4         }

  该事件处理程序功能和原来是类似的。

  运行程序,先后点击只有文本的ListBoxItem和带有CheckBox控件的ListBoxItem,我们注意对比两者的不同。

  点击只有文本的ListBoxItem。

  

  单击带有CheckBox控件的ListBoxItem   

  

  我们发现当单击只有文本的ListBoxItem的时候,在TextBlock控件的ManipulationCompleted事件后,触发了ListBox的SelectionChanged事件,而单击带有CheckBox控件的ListBoxItem的时候并没有触发ListBox的SelectionChanged事件,事实上这就是问题的关键所在。  

  当ListBoxItem中包含着对单击或触摸有特殊处理的控件(Button、CheckBox、RatioButton)的时候,不会触发ListBox的SelectionChanged事件,会将事件继续向上传递。而ListBoxItem中仅仅有自身对单击或触摸没有特殊处理的控件(TextBlock Image),就会触发ListBox的SelectionChanged事件,而SelectionChanged就不会向上继续传递了。因为已经到了顶级元素ListBox那里。这就是冒泡路由事件的向上传递被中断的原因。  

  好了,到现在大家对应该windows phone中的路由事件应该已经有了一个大致的了解,希望大家能自己建立一个示例程序,试验一下其他控件在ListBox中的表现,这样能够更加深刻的理解路由事件。

  相关视频请参考:http://v.youku.com/v_show/id_XMzc4NTc2ODIw.html 

来源:http://www.th7.cn/Program/wp7/2012/04/10/69103.shtml

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机号码注销了微信忘记密码怎么办 微信忘记密码手机号码也换了怎么办 微信钱包里的钱莫名少了怎么办 被骗给人冲q币了怎么办 支付宝账户异常无法领取红包怎么办 微信q币支付错了怎么办 王者荣耀不小心把点卷用了怎么办 微信绑定的qq号密码忘记了怎么办 微信红包实名认证没银行卡怎么办 手机烂了换新手机微信支付宝怎么办 支付宝转账给别人号码没用了怎么办 微信转账验证码收不到怎么办 陌生网友生日叫我发红包怎么办 微信群的群主不小心推出群该怎么办 支付宝验证码被别人知道了怎么办 微信解除银行卡绑定零钱清零怎么办 qq号被盗了理财通的钱怎么办 工行转错账号的钱被冻结怎么办 微信20w限额满了怎么办 通过qq号申请微信被盗了怎么办 微信号被盗手机绑定被改怎么办 腾讯视频激活码兑换达到限制怎么办 虚拟服务购买自动每月扣q币怎么办 微信被骗充值Q币怎么办 微信给别人充q币怎么办 k歌别人送的k币怎么办 忘记了qq号码但记得密码怎么办 q自己的活干完了该怎么办 在应用宝下载的游戏搜不到了怎么办 衣服有图片在淘宝找不到同款怎么办 淘宝卖家小儿说质量不合格怎么办 订单显示显示已签收没收到货怎么办 网上买过的东西查不到订单号怎么办 亚航的组合机票飞机延误怎么办 在微信上面对面红包被骗了钱怎么办 人欠我钱不给我怎么办 微信号被骗走然后骗了朋友钱怎么办 微信手机充值不到帐怎么办 中银香港密码器坏了怎么办 香港恒生银行的编码器丢了怎么办 淘宝拍下订单发货物流不显示怎么办