zoukankan      html  css  js  c++  java
  • WPF基础之路由事件五

    EventSetter 和 EventTrigger 
    在样式中,可以通过使用 EventSetter 在标记中包括某个预先声明的 XAML 事件处理语法。在应用样式时,所引用的处理程序会添加到带样式的实例中。只能针对路由事件声明 EventSetter。下面是一个示例。请注意,此处引用的 b1SetColor 方法位于代码隐藏文件中。

     

    这样做的好处在于,样式有可能包含大量可应用于应用程序中任何按钮的其他信息,让 EventSetter 成为该样式的一部分甚至可以提高代码在标记级别的重用率。而且,EventSetter 还进一步从通用的应用程序和页面标记中提取处理程序方法的名称。

    另一个将 WPF 的路由事件和动画功能结合在一起的专用语法是 EventTrigger。与 EventSetter 一样,只有路由事件可以用于 EventTrigger。通常将 EventTrigger 声明为样式的一部分,但是还可以在页面级元素上将 EventTrigger 声明为 Triggers 集合的一部分或者在 ControlTemplate 中对其进行声明。使用 EventTrigger,可以指定当路由事件到达其路由中的某个元素(这个元素针对该事件声明了 EventTrigger)时将运行的 Storyboard。与只是处理事件并且会导致它启动现有演示图板相比,EventTrigger 的好处在于,EventTrigger 对演示图板及其运行时行为提供更好的控制。

    本主题主要从以下角度讨论路由事件:描述基本概念;就如何以及何时响应各种基元素和基控件中已经存在的路由事件提供指南。但是,您可以为自定义类创建自己的路由事件,还可以创建所有必要的支持(如专用的事件数据类和委托)。路由事件的所有者可以是任何类,但是路由事件只有在由 UIElement 或 ContentElement 派生类引发和处理之后才有用。

    可扩展应用程序标记语言 (XAML) 定义了一个语言组件和称为“附加事件”的事件类型。附加事件的概念允许您针对特定事件为任意元素(而不是为实际定义或继承该事件的元素)添加处理程序。在这种情况下,对象既不会引发该事件,目标处理实例也不会定义或“拥有”该事件。

    先决条件 
    本主题假定您已阅读路由事件概述和 XAML 概述。

    附加事件语法 
    附加事件具有一种 XAML 语法和编码模式,后备代码必须使用该语法和编码模式才支持附加事件的使用。

    在 XAML 语法中,不仅可以通过事件名称来指定附加事件,而且还可以通过用点 (.) 分隔的事件拥有类型加上事件名称来指定。因为事件名称是使用其拥有类型的名称限定的,所以附加事件语法允许将任何附加事件附加到可以实例化的任何元素上。

    例如,下面是为自定义 NeedsCleaning 附加事件附加处理程序的 XAML 语法:

     

    请注意 aqua: 前缀;该前缀在本例中是必需的,因为附加事件是来自自定义映射 xmlns 的自定义事件。

    如何在 WPF 中实现附加事件 
    在 WPF 中,附加事件由 RoutedEvent 字段来支持,并在引发后通过元素树进行路由。通常,附加事件的源(引发该事件的对象)是系统或服务源,所以运行引发该事件的代码的对象并不是元素树的直接组成部分。

    附加事件的方案 
    在 WPF 中,附加事件存在于具有服务级抽象的某些功能区域,例如,对于通过静态 Mouse 类或 Validation 类实现的事件。与服务交互或使用服务的类可以在附加事件语法中使用该事件,也可以选择将附加事件作为路由事件来实现(这是类如何集成服务功能的一部分)。

    尽管 WPF 定义了许多附加事件,但您直接使用或处理附加事件的方案却很有限。一般情况下,附加事件用于实现体系结构目的,但随后即被转发给非附加(使用 CLR 事件“包装”提供支持)路由事件。

    例如,通过针对该 UIElement 使用 MouseDown(而不是在 XAML 或代码中处理附加事件语法),可以针对任何给定的 UIElement 更方便地处理基础附加事件 Mouse..::.MouseDown。附加事件用于实现体系结构目的,因为它允许进一部扩展输入设备。假设的设备只需引发 Mouse..::.MouseDown 即可模拟鼠标输入,而不需要从 Mouse 派生。但是,此方案会涉及事件的代码处理,而附加事件的 XAML 处理则与此方案无关。

    在 WPF 中处理附加事件 
    处理附加事件的过程以及您将要编写的处理程序代码与路由事件基本相同。

    一般情况下,WPF 附加事件与 WPF 路由事件并没有太大的区别。不同之处在于如何确定事件的源,以及如何通过类将事件作为成员进行公开。(这还将影响 XAML 处理程序语法。)

    但是,正如前文所述,现有的 WPF 附加事件并不是专门用于在 WPF 中进行处理。该事件的目的常常是实现合成元素,以便向合成中的父元素报告某个状态,在这种情况下,该事件常常在代码中引发,并且还依赖于相关父类中的类处理。例如,Selector 中的项应引发附加的 Selected 事件,该事件随后将由 Selector 类进行类处理,然后可能由 Selector 类转换为不同的路由事件 SelectionChanged。

    将您自己的附加事件定义为路由事件 
    如果您从通用 WPF 基类派生,则可以通过在类中包括某些模式方法并使用基类中已经存在的实用工具方法来实现您自己的附加事件。

    模式如下:

    带有两个参数的方法 Add*Handler。第一个参数必须标识事件,而标识的事件必须与方法名称中带有 * 的名称相匹配。第二个参数是要添加的处理程序。该方法必须是公共且静态的,没有任何返回值。

    带有两个参数的方法 Remove*Handler。第一个参数必须标识事件,而标识的事件必须与方法名称中带有 * 的名称相匹配。第二个参数是要移除的处理程序。该方法必须是公共且静态的,没有任何返回值。

    当针对某个元素声明附加事件处理程序属性时,Add*Handler 访问器方法可以加快 XAML 处理。Add*Handler 和 Remove*Handler 方法还可实现对附加事件的事件处理程序存储区的代码访问。

    这个普通模式对于框架中的实际实现还不够精确,因为任何给定的 XAML 读取器实现都可能采用不同的架构在支持语言和体系结构中标识基础事件。这是 WPF 将附加事件作为路由事件来实现的原因之一;用于事件的标识符 (RoutedEvent) 已经由 WPF 事件系统进行定义。而且,路由一个事件也是对附加事件的 XAML 语言级概念的自然实现扩展。

    WPF 附加事件的 Add*Handler 实现包括将路由事件和处理程序用作参数来调用 AddHandler。

    此实现策略和路由事件系统一般将附加事件的处理限制为 UIElement 派生类或 ContentElement 派生类,因为只有这些类才具有 AddHandler 实现。

    例如,下面的代码按照 WPF 将附加事件作为路由事件进行声明的附加事件策略为所有者类 Aquarium 定义 NeedsCleaning 附加事件。

     

    请注意,用来确定附加事件标识符字段的方法 RegisterRoutedEvent 实际上与用来注册非附加路由事件的方法相同。附加事件和路由事件都是在集中管理的内部存储区中进行注册的。此事件存储区实现则实现了路由事件概述中讨论的“事件作为界面”概念方面的注意事项。

    引发 WPF 附加事件 
    通常不需要从代码中引发 WPF 定义的现有附加事件。这些事件采用一般的“服务”概念模型,而服务类(如 InputManager)则负责引发事件。

    但是,如果您根据将 RoutedEvent 作为附加事件基础的 WPF 模型来定义自定义附加事件,则可以使用 RaiseEvent 从任何 UIElement 或 ContentElement 中引发附加事件。引发路由事件(不管是否附加)要求您在元素树中声明一个特定的元素作为事件源;该事件源被报告为 RaiseEvent 调用方。您的服务负责决定将哪个元素报告为元素树中的事件源。

    以上路由事件的相关介绍转自银光中国,大家共同学习

  • 相关阅读:
    shiro角色与权限
    shiro Realm体系
    shiro AuthenticationToken体系
    shiro身份认证流程
    git相关
    Logback 快速入门 / 使用详解
    SLF4J 快速入门 / 绑定原理
    Java 日志框架概述(slf4j / log4j / JUL / Common-logging(JCL) / logback)
    Java 浮点数精确性探讨(IEEE754 / double / float)与 BigDecimal 解决方案
    Maven 快速入门
  • 原文地址:https://www.cnblogs.com/jljxxf/p/2494756.html
Copyright © 2011-2022 走看看