• Win10系列:UWP界面布局基础8


    路由事件

    XAML不仅继承了传统的事件处理方式,还引入了一个增强型事件处理机制:路由事件(RoutedEvent)。路由事件和传统事件的不同是:路由事件允许一个对象触发事件后,可以同时拥有多个事件接收者。也就是说,路由事件可以针对多个对象(而不是仅针对触发该事件的对象)调用事件处理程序。

    在XAML文件中,所有的元素对象构成一种嵌套结构,当应用程序运行时,也将按照层次结构顺序由外到内对这些元素对象进行初始化,最终生成一个对象树,在Windows应用商店的空白应用程序项目中,最终生成一个以Page元素为根的对象树。基于对象树的概念,XAML中路由事件处理方式可分为以下三种:

    (1)冒泡路由方式。一个对象触发事件后,事件将沿着对象树由下至上,由子元素对象到父元素对象传播扩散,直到到达对象树的根元素,或者该事件的Handled属性取值为true时,完成处理。在传播扩散中,所有涉及的元素对象都会调用相应的事件处理程序

    (2)隧道路由方式。该类事件处理方式和冒泡方式相反,在对象触发事件后,事件将从根对象传播扩散到触发该事件的对象,或者该事件的Handled属性取值为 true时,完成处理。

    (3)直接路由方式。在这种处理方式中事件不进行向上或向下传播扩散,仅作用于触发该事件的当前对象上。

    下面以冒泡路由方式为例来演示路由事件的处理过程。新建一个Windows应用商店的空白应用程序项目,将其命名为BubblingRoutedEventApplication,打开项目下的MainPage.xaml文件,在Grid元素中添加如下代码:

    <Grid PointerPressed="Grid_PointerPressed" Height="250" Width="300" Background="Black">

    <TextBlock Text="Grid控件" FontWeight="Bold" Margin="5"/>

    <Canvas Background="Gray" PointerPressed="Canvas_PointerPressed" Margin="29,30,25,35">

    <TextBlock Text="Canvas控件" FontWeight="Bold" Foreground="White" Margin="5"/>

    <StackPanel Height="117" Width="196" Background="Black" Canvas.Top="30" Canvas.Left="26" PointerPressed="StackPanel_PointerPressed">

    <TextBlock Text="StackPanel控件" FontWeight="Bold" Margin="5"/>

    <TextBlock Text="事件冒泡顺序是:" FontWeight="Bold" Margin="5"/>

    <TextBox Name="ShowEventOrder" BorderBrush="Gray" Background="Black" FontSize="10" Foreground="White" TextWrapping="Wrap" Margin="10,0" Height="65"/>

    </StackPanel>

    </Canvas>

    </Grid>

    在上面的代码中,添加了一个Grid控件,设置背景色为黑色,并为PointerPressed事件注册了处理方法Grid_PointerPressed,同时在该控件内部添加了一个TextBlock控件和一个Canvas控件, 其中TextBlock控件的文本内容为"Grid控件",Canvas控件的背景色为灰色,并为Canvas控件的PointerPressed事件注册了处理方法Canvas_PointerPressed。接着在Canvas控件内又添加了一个TextBlock控件和一个StackPanel控件,TextBlock控件的文本内容为"Canvas控件",文本颜色为白色,StackPanel控件的背景色为黑色,并为PointerPressed事件注册了处理方法StackPanel_PointerPressed。最后在StackPanel控件中,先添加了两个TextBlock文本块,其中一个文本块的文本内容为"StackPanel控件",另一个文本块的文本内容为"事件冒泡顺序是:",随后又定义了一个文本框,将其命名为ShowEventOrder,并分别设置文本框的边框颜色和字体颜色等。

    布局好前台界面后,打开MainPage.xaml.cs文件,分别为Grid控件、Canvas控件和StackPanel控件的PointerPressed事件定义相应的事件处理方法。

    Grid控件的PointerPressed事件处理方法Grid_PointerPressed的代码片段如下所示:

    private void Grid_PointerPressed(object sender, PointerRoutedEventArgs e)

    {

    ShowEventOrder.Text += "Grid; ";

    e.Handled = true;

    }

    在上面的代码中,将"Grid; "字符串追加到ShowEventOrder文本框中,并通过设置参数e的Handled属性值为true来停止事件传播。

    Canvas控件的PointerPressed事件处理方法Canvas_PointerPressed的代码片段如下所示:

    private void Canvas_PointerPressed(object sender, PointerRoutedEventArgs e)

    {

    // 将"Canvas - "字符串追加到ShowEventOrder文本框中

    ShowEventOrder.Text += "Canvas - ";

    }

    StackPanel控件的PointerPressed事件处理方法StackPanel_PointerPressed的代码片段如下所示:

    private void StackPanel_PointerPressed(object sender, PointerRoutedEventArgs e)

    {

    // 将"StackPanel - "字符串追加到ShowEventOrder文本框中

    ShowEventOrder.Text += "StackPanel - ";

    }

    启动调试,未单击任何控件区域之前的效果如图3-13所示。

    图3-13 界面初始状态

    当单击Grid控件区域时,Grid对象会触发PointerPressed事件,并且调用相应的事件处理方法Grid_PointerPressed,完成将字符串"Grid; "追加到ShowEventOrder文本框中。这时,事件的Handled属性值已经为true,所以事件停止扩散,最终产生的结果如图3-14所示。

    图3-14 单击Grid控件区域产生的结果

    当单击Canvas控件区域时,Canvas对象会触发PointerPressed事件,并且调用相应的事件处理方法Canvas_PointerPressed,完成将字符串"Canvas- "追加到ShowEventOrder文本框中。由于Canvas对象还有一个父对象Grid,因此事件会继续向上传播,调用Grid的事件处理方法Grid_PointerPressed事件传到Grid对象后就停止传播,最终产生的结果如图3-15所示。

    图3-15 单击Canvas控件区域产生的结果

    当单击StackPanel控件区域时,StackPanel对象会触发PointerPressed事件,并且调用相应的处理方法StackPanel_PointerPressed,完成将字符串"StackPanel - "追加到ShowEventOrder文本框中。由于StackPanel对象上面还有父对象,因此事件会继续向上传播,依次调用Canvas对象的事件处理方法Canvas_PointerPressed和Grid对象的事件处理方法Grid_PointerPressed。待事件传到Grid对象后,将停止传播,最终产生的结果如图3-16所示。

    图3-16 单击StackPanel控件区域产生的结果

  • 相关阅读:
    Maven下Flex国际化配置
    Adobe AIR and Flex
    jQuery: 刨根问底 attr and prop两个函数的区别
    HTML5[8]: 图文混排,图片与文字居中对齐
    HTML5[7]: 实现网页版的加载更多
    HTML5[6]:多行文本显示省略号
    HTML5[5]:在移动端禁用长按选中文本功能
    HTML5[4]:去除不必要的标签,完全使用css实现样式
    HTML5[3]:中文换行
    HTML5[2]:使用viewport控制手机浏览器布局
  • 原文地址:https://www.cnblogs.com/finehappy/p/6645738.html
走看看 - 开发者的网上家园