介绍一下事件的编程概念、事件概念如何在 Silverlight 中发挥作用及其编程模型。

Silverlight 事件与公共语言运行时和 .NET Framework 对于事件概念的定义在本质上是相同的。与 WPF 类似,我们可以将事件的处理程序分配为 XAML 中 UI 元素的声明的一部分,也可以使用语言特定的语法在代码中添加处理程序。Silverlight 支持路由事件的概念,通过路由事件这一功能,某些输入事件和数据事件可以由除引发事件的对象之外的其他对象进行处理。当组合控件模板或集中处理应用程序页的事件逻辑时,路由事件特别有用。

一.事件作为编程概念

事件是对象发送的消息,以发信号通知操作的发生。操作可能是由用户交互(例如鼠标单击)引起的,也可能是由某个类的内部逻辑触发的。引发事件的对象称为事件发送方。捕获事件并对其作出响应的对象叫做事件接收方。总体而言,事件的作用是交流某个对象在运行时的时间特定的、相对轻量的信息,并可能将该信息传送到应用程序中的其他对象。

Silverlight 事件

一般而言,Silverlight 事件是 CLR 事件,因此是可以使用托管代码来处理的事件。

由于 UI 是在标记 (XAML) 中定义的,因此,其编程的某些原则类似于 ASP.NET或使用 HTML DOM。

Silverlight 还有一些事件要求插件实例本身具有处理程序,例如 OnError 事件。这些事件由针对 HTML DOM 中的插件实例运行的任何脚本公开,并可能由此脚本进行处理。HTML 脚本应具有第一个机会进行处理,因此,这些事件不传递到托管 API。我们的托管宿主网页中就有这样的代码。

说明:因为 Silverlight 在宿主浏览器的插件体系结构中工作,所以,输入事件的输入促进因素最初由浏览器处理。然后,输入信息通过该浏览器用于支持一般插件的 API 发送到 Silverlight 插件,您可以处理在 Silverlight API 中定义的相应事件。Silverlight 中大多数其他的非输入事件并不一定具有此类浏览器问题。

二.Button.Click:使用 Silverlight 事件简介

由于 Silverlight 属于 UI 技术,因此,我们要执行的最常见任务之一是捕获用户对 UI 的输入。例如,UI 可能具有一个按钮,用户必须单击此按钮才能提交信息或更改应用程序的状态。

通常,我们可以通过生成 XAML 为基于 Silverlight 的应用程序定义 UI。此 XAML 可以是来自诸如 Expression Blend的设计器和诸如 Silverlight Designer for Visual Studio 的设计图面的输出,也可能是在文本编辑器中编写出来的。作为生成该 XAML 的一部分,我们可以在定义用于描述该 UI 元素的所有其他属性的同时,为各个 UI 元素连结事件处理程序。XAML 中的事件连结涉及到提供处理程序方法的名称。

例如,下面的XAML代码定义一个Button对象,并为按钮的Click事件连接一个处理程序:

<Button Name="UpdateButton" Content="Update" Click="showUpdatesButton_Click"/>

而实际的处理程序是用Silverlight支持的.net框架语言编写的。如(vb,c#)

通过Click=”showUpdatesButton_Click”,我们已经创建一个协定,当编译XAML时,XAML编译器可以找到一个名为showUpdatesButton_Click的方法。此外对于这个方法还有这样的一些规定:它实现特定的方法签名(基于委托),而该方法签名是Click事件的任何处理程序所必须的。

定义 showUpdatesButton_Click 处理程序:

private void showUpdatesButton_Click (object sender, RoutedEventArgs e)

{

//业务逻辑

}

我们编写的处理程序必须与该委托签名匹配:上面的示例,委托为RouteEventHandler

要强调的一点:调用 Silverlight 事件处理程序函数时不能使用参数值(即使是空参数值也不例外),这一点与 HTML DOM 中的事件处理程序语法明显不同。属性值只是引用处理程序名称,而其他机制(例如,处理程序的预期输入参数)负责传递信息。

三:定义事件处理程序

         对于作为在 XAML 中声明的 UI 的对象,必须在充当 XAML 页的代码隐藏的分部类中定义事件处理程序代码。

分部类中的事件处理程序根据由该特定事件使用的 CLR 委托编写为方法。事件处理程序方法可以是公共方法,也可以具有私有访问级别。私有访问将发挥作用,因为由 XAML 创建的处理程序和实例最终将通过代码生成来进行联接。一般建议是不要让事件处理程序方法在类中成为公共方法。

 

 

四.sender参数和事件参数

我们为托管的 Silverlight 事件编写的任何处理程序都可以访问两个值,这两个值对于调用处理程序的每种情况都可以用作输入。第一个此类值是 sender。sender 是对于在其中附加处理程序的对象的引用。sender 类型化为基本 Object 类型。如果您预计要检查或更改 sender 对象自身的状态,并且您知道根据处理程序所附加到的位置或有关应用程序的其他特定信息,可以安全地将 sender 强制转换为某种类型,则一种常用的 Silverlight(和 WPF)事件处理方法是将 sender 强制转换为更精确的类型。

第二个值是事件数据,它通常作为 e 参数出现在签名中。根据 CLR 事件模型,所有事件均发送某种事件数据,并且这些数据将作为某个类的实例被捕获,而该类将以某种方式继承 EventArgs(或为 EventArgs 本身)。您可以通过查找为您正在处理的特定事件分配的委托的 e 参数,然后使用 Visual Studio 中的 Intellisense 或 Silverlight 的 .NET 引用库,查找事件数据的哪些属性是可用的。

对于某些事件,EventArgs 派生类中的事件数据与知道事件被引发同样重要。对于输入事件尤其如此。对于鼠标事件,事件发生时鼠标的位置可能很重要。对于键盘事件,键盘上的键引发相同的 KeyUp 和 KeyDown 事件。为了确定按下了哪个键,必须访问可用于事件处理程序的 KeyEventArgs。

五.在托管代码中添加事件处理程序

XAML 并不是向对象分配事件处理程序的唯一方式。若要在托管代码中将事件处理程序添加到任何给定对象(包括添加到甚至在 XAML 中不可用的对象),可以使用特定于 CLR 语言的语法来添加事件处理程序。在 C# 中,此语法是使用 += 运算符,并通过使用事件处理程序方法名称来声明新委托以实例化处理程序。

如果您使用代码将事件处理程序添加到的确在运行时 UI 中显示的对象,则 Silverlight 的通用做法是添加此类处理程序以响应对象生存期事件(例如,Loaded 或 OnApplyTemplate),以便相关对象上的事件处理程序准备好处理在运行时用户启动的事件。下面的示例首先介绍了 XAML 概况以提供有关结构的一些思路,然后给出了 C# 语言语法。

<Grid x:Name="LayoutRoot" Loaded="LayoutRoot_Loaded">

<StackPanel>

<TextBlock Name="textBlock1">Put the mouse over this text</TextBlock>

</StackPanel>

</Grid>

 

.xaml.cs代码

void LayoutRoot_Loaded(object sender, RoutedEventArgs e)

{

textBlock1.MouseEnter += new MouseEventHandler(textBlocks_MouseEnter);

textBlock1.MouseLeave += new MouseEventHandler(textBlocks_MouseLeave);

}

六.路由事件

对于在基类中定义的并在支持用户交互和输入的大多数 UI 元素中存在的若干输入事件,Silverlight 支持路由事件的概念:

·         KeyDown

·         KeyUp

·         GotFocus

·         LostFocus

·         MouseLeftButtonDown

·         MouseLeftButtonUp

·         MouseMove

·         MouseWheel

·         BindingValidationError

路由事件是在对象树中可能从某个子对象传递(路由)到其每个后续父对象的事件。所涉及的对象树与 UI 的 XAML 结构近似,该树的根成为 XAML 中的根元素。真正的对象树可能与 XAML 稍有不同,因为对象树不包括 XAML 语言功能(如属性元素标记),但通常可将路由事件视为从引发该事件的 XAML 对象元素子项向包含它们的父对象元素"冒泡"并持续路由,直到到达根元素。

说明一下:

WPF 支持类似的"隧道"路由策略,因此,页/对象树的根首先有机会来处理路由事件,然后,该事件通过"隧道"沿着对象树向下传递到其事件源。Silverlight 不使用"隧道"传递路由事件。Silverlight 中的事件要么遵循"冒泡"路由策略(也称为路由事件),要么根本不路由。Silverlight 与 WPF 之间的路由事件行为还存在着其他 API 级别差异。

RoutedEventArgs 的 OriginalSource 属性

当事件向上冒泡事件路由时,sender 不再是与事件引发对象相同的对象。相反,sender 是在其中附加正在调用的处理程序的对象。在许多情况下,sender 不是您感兴趣的对象;您而是更希望了解鼠标位于哪些可能的子对象上方,或当按下键盘键时哪个对象具有焦点等此类信息。对于这些情形,OriginalSource 属性的值是您感兴趣的对象。

在路由的所有点上,OriginalSource 报告引发事件的原始对象,而不是附加处理程序的位置。对于上述方式有用的示例方案,请考虑这样一个应用程序:在该应用程序中,您希望某些键组合成为"热键"或快捷键,而不考虑哪个控件当前持有键盘焦点并启动事件。就对象树而言,具有焦点的对象可能嵌套在列表框中包括某些项的列表内,也可能是整个用户界面中的众多对象之一。如果必须将处理程序附加到应用程序中每个可能获得焦点的对象才能检测到快捷键,则这很明显是不切实际的。但是,因为键盘事件正在冒泡路由事件,所以,该事件最终会在其路由中到达根对象。因此,您通常可以在根对象上附加单个 KeyDown 处理程序,并依赖于 KeyDown 事件最终冒泡到根对象的行为。然后,处理程序可以确定该键是否为预期快捷键操作的有效组合,或者是否不需要执行操作。

Handled 属性

特定路由事件的多个事件数据类包含一个名为 Handled 的属性。有关示例,请参见 MouseButtonEventArgs..::..Handled、KeyEventArgs..::..Handled、MouseWheelEventArgs..::..Handled 和 ValidationErrorEventArgs..::..Handled。Handled 是一个可设置的布尔值属性。

将 Handled 属性设置为 true 会影响 Silverlight 中的事件系统。当您在事件数据中将该值设置为 true 时,路由将因为大多数事件处理程序而停止;事件不会继续路由来向其他附加的处理程序通知该特定的事件。"已处理"作为一个操作在事件上下文中意味着什么以及应用程序如何响应完全取决于您。但是,当您选择在事件处理程序中设置 Handled 时,应确保注意 Silverlight 事件系统的这一行为。

并非所有路由事件都可用这种方法取消。GotFocus、LostFocus 和 MouseMove 将始终一直路由到根目录,其事件数据类没有可影响该行为的 Handled 属性。因此,针对这些事件检查 OriginalSource 值通常是一个好主意,可确保您不处理事件,也不对事件的含义和如何确定其来源进行不正确的假设。

可视化树外的路由事件

Silverlight 中的某些对象涉及与主要可视化树的关系,主要可视化树在概念上类似在主要可视化元素上重叠,并且不是将所有树元素连接到可视根的常见父-子关系的一部分。任何显示的 Popup 或 ToolTip 就是这种情况。如果您要处理来自 Popup 或 ToolTip 的路由事件,则应将处理程序放置于 Popup 或 ToolTip 内的特定 UI 元素上(而非 Popup 或 ToolTip 元素本身上),并且不应依赖于为 Popup 或 ToolTip 内容实现的任何合成内的路由。这是因为对路由事件的事件路由仅适用于主可视化树。Popup 或 ToolTip 不视为子一级 UI 元素的父级,并且永远不接收路由事件,即使正在尝试使用类似 Popup 默认背景这样的内容作为输入事件的捕获区域。

 

七.用户启动的事件、全屏模式

Silverlight 坚持只允许某些操作在处理用户启动的事件的处理程序的上下文中执行:

·         设置 IsFullScreen

·         显示 SaveFileDialog

·         从 HyperlinkButton 导航

Silverlight 用户启动的事件包括鼠标事件(如 MouseLeftButtonDown)以及键盘事件(如 KeyDown)。基于此类事件(如 Click)的控件的事件也被视为用户启动的事件。

一旦 Silverlight 处于全屏模式,将出于安全原因而特意禁止某些输入事件。

八.移除事件处理程序

在某些情况下,我们可能希望在应用程序生存期中移除事件处理程序。若要移除事件处理程序,请使用特定于 CLR 语言的语法。在 C# 中,使用 -= 运算符。

void Cleanup()

{

...

textBlock1.MouseEnter -= textBlocks_MouseEnter;

}

如果事件是通过 XAML 属性添加的,则也可以移除处理程序。如果我们为在其中附加处理程序的元素提供了 Name 值,则这一点实现起来更为容易,因为该元素稍后为代码提供了对象引用,但我们还可以在对象树中导航以查找所需的对象引用(如果我们必须这么做)。

Silverlight学习之——事件编程相关推荐

  1. SilverLight学习笔记--如何解决Button不响应MouseLeftButtonDown与MouseLeftButtonUp事件的问题...

    在Silverlight 2 中的按钮不能响应MouseLeftButtonDown 和 MouseLeftButtonUp 事件,为解决此问题,我们可通过创建自定义按钮控件加以解决, 1.创建自定义 ...

  2. Silverlight学习资源更新

    原文出处:http://kevinfan.blog.51cto.com/1037293/727892 本周Silverlight学习资源更新 Silverlight 利用Telerik导出到Word ...

  3. SilverLight学习笔记--Silverlight之数据绑定初探

    数据绑定(Data Binding)是用户界面UI和业务对象或其它数据提供者(data provider)的连接.用户界面对象称为目标,数据提供者成为数据源.   数据绑定帮助隔离应用程序的用户界面层 ...

  4. SilverLight学习笔记--建立Silverlight自定义控件(5)--绑定动画效果

    有了上述的基础,我们进一步完善我们的自定义控件,在此我们将创建Storyboard和前面的添加事件处理方法为我们的自定义控件加上动画效果.   1.首先,在MyDesignButton项目中进一步完善 ...

  5. 三种方式实现观察者模式 及 Spring中的事件编程模型

    观察者模式可以说是众多设计模式中,最容易理解的设计模式之一了,观察者模式在Spring中也随处可见,面试的时候,面试官可能会问,嘿,你既然读过Spring源码,那你说说Spring中运用的设计模式吧, ...

  6. SilverLight学习笔记--建立Silverlight自定义控件(1)--外观设计

    Silverlight 2 以丰富且强大可靠的控件模型闻名,该模型是平台中包括的控件和第三方控件包的基础.您也可以使用此控件模型构建自己的控件.   在了解如何为新平台编写自定义控件时,我经常先复制一 ...

  7. SilverLight学习笔记--如何在xaml文件中操作用户在后台代码定义的类(2)--示例篇:创建一个登录控件(原创)(转载本文请注明出处)...

    本文将示例如何运用前篇所写知识来建立一个用户自定义的登录控件.此控件界面非常简单,主要涉及的知识点是:   如何创建用户控件(包括对此控件的自定义事件和属性的编写,此处我们将创建一个名为LoginBo ...

  8. Silverlight学习(一) 创建Silverlight项目,构建一个简单的Silverlight Demo

          今天我将开始我的Silverlight学习之旅.首先学会如何创建Silverlight项目并构建一个Silverlight简单的Hello World Demo. 创建项目   现在Sil ...

  9. python网络编程视频教程_Java网络开发视频教程 – 一站式学习Java网络编程视频教程 全面理解BIO(无密)...

    Java网络开发视频教程 – 一站式学习Java网络编程视频教程 全面理解BIO(无密) 全面理解BIO/NIO/AIO 网络层编程,是每一个开发者都要面对的技术.课程为解决大家学习网络层知识的难题, ...

最新文章

  1. sql特殊字符转义,oracle中将字符 ‘ 转义
  2. GDCM:gdcm::PhotometricInterpretation的测试程序
  3. linux pxe启动ftp格式,FTP+DHCP+TFTP+PXElinux实现RHLINUX的网络自动安装
  4. Context.PROVIDER_URL 逗号间隔
  5. 密码学专题 密钥生成|分组加密的模式 ECB|CBC|CFB|OFB
  6. 干货时间:聊聊DevOps下的技术系列之契约测试
  7. 2017.9.23 新Nim游戏 失败总结
  8. opencv 利用图像轮廓函数填充圆环内部 图像轮廓函数应用小例子
  9. pythonATM,购物车项目实战5-数据处理层
  10. opencv 图像对比度、亮度值调整 和滑动条
  11. QML 获取当前时间戳 yyyy-MM-dd hh:mm:ss.zzz
  12. 改步数最新方法与工具,很好用
  13. 华为设备VRRP配置命令
  14. B编码以及BT种子文件分析
  15. Win7添加打印机local port端口拒绝访问的解决方法
  16. 全国计算机比赛图片,我校学子获2020年“中国高校计算机大赛-网络技术挑战赛”全国总决赛一等奖(图)-全国文明校园建设网...
  17. 优惠券和让利哪种营销方式更好?
  18. java计算机毕业设计ssm基于SSM学生信息管理系统37myx(附源码、数据库)
  19. [4G+5G专题-140]: 终端 - 5G终端主要的产品形态 - 行业终端
  20. c语言程序设计例案教程,C语言程序设计案例教程

热门文章

  1. UVa10911 Forming Quiz Teams(dp)
  2. java I/O思维导图
  3. qt中显示文件夹下的目录及文件的过滤
  4. 虚拟机和主机ping不通,SQL Server无法远程连接的解决方法
  5. 【php】(转载)分享一个好用的php违禁词 处理类
  6. Java新手问题 02 面向对象基本功
  7. 聊一聊IAR的workspace文件组织
  8. AFNetworking 2.0使用(持续更新)
  9. com+ 三层布署[未成功验证]
  10. IT人的理性、激情与爱情