zoukankan      html  css  js  c++  java
  • WPF 路由事件

    路由事件是具有更强传播能力的事件,它们可在元素树中向上冒泡和向下隧道传播,并且沿着传播路径被事件处理程序处理。

    理解路由事件

    当有意义的事情发生时,由对象发送的用于通知代码的消息。

    事件路由允许源自某个元素的事件由另一个元素引发。

    比如·来自工具栏按钮的单击事件可在代码处理之前上传到工具栏,然后上传到包含工具栏的窗口。

    定义,注册和封装路由事件

    依赖项属性是使用DependencyProperty.Register方法注册的,路由事件是使用EventManager.RegisterRoutedEvent()方法注册的

    注册事件时,需要指定事件的名称,路由类型,定义事件程序程序语法的委托,和拥有的事件类

    通常,路由事件通过普通的.Net事件进行封装,从而使所有的.Net语言都能访问它们,事件封装器可使用AddHandler()和RemoveHandler()方法添加和删除已注册的调用程序

     例如Button类提供了大家熟悉的Click事件

    共享路由事件

    与依赖项属性一样,可在类之间共享路由事件的定义。比如 UIElement(是普通WPF元素的起点)和Content(该类是所有内容的起点)。两个基类都用了MouseUp事件。

     引发路由事件

    使用RaiseEvent()方法引发事件

    RaiseEvent方法负责为每个已经通过AddHandler方法注册的调用程序引发事件,因为AddHandler方法是公有的,所以调用程序可访问该方法---它们能够通过直接调用AddHandler方法注册自己,也可以使用事件封装器。无论使用哪种办法,当调用RaiseEvent方法是都会通知它们。

    事件处理程序的第一个参数sender参数都提供引发该事件的对象引用。第二个参数是EventArgs对象,该对象与其他所有可能很重要的附加细节绑定在一起。MouseUp事件提供了一个MouseEventAgrs对象,用于指示当事件发生时按下哪些鼠标键

    在WPF中,如果事件不需要传递任何额外细节,可使用RoutedEventArgs类,该类包含了有关如何传递事件的一些细节,如果事件确实需要传递额外的信息,那么需要使用更特殊的继承自RoutedEventArgs的对象。

    处理路由事件

    可用多种方法关联事件处理程序。最常用的方法是为XAML标记添加事件特性。

     也可以使用代码连接事件

    上面的代码创建了一个针对该事件具有正确签名的委托对象,并将该委托指向img_MouseUp方法。然后将该委托添加到img.MouseUp事件的已注册的事件程序程序列表中

     

    也可以自行通过UIElement.AddHandler方法直接连接事件

    使用这种办法,始终需要创建合适的委托类型,而不能隐式地创建委托对象,这是因为UIElement.AddHandler方法支持所有的WPF事件,并且它不知道你想使用的委托类型

    或者使用:

    断开事件处理程序

    事件路由

     比如:

    对每个元素的MouseDown和MouseUp事件关联同一个事件处理程序,这样会使得标记变得杂乱无章难以维护,WPF使用路由事件模型提供了良好的解决方案

    • 直接路由事件,源于一个元素,不传递给其他元素。比如:MouseEnter事件(鼠标移动到元素上发生)是直接路由事件
    • 冒泡路由事件,该事件被单击的元素引发,接下来被该元素的父元素引发,直到元素树的顶端
    • 隧道路由事件,隧道路由事件给到达恰当的控件之前为预览事件提供了机会。比如PreviewKeyDown事件可截获是否按下了某个键。首先在窗口级别,然后是具体的容器,直到到达当按下键时具有焦点的元素

    当使用EventManager.RegisterEvent方法注册路由事件时,需要传递一个RoutingStrategy枚举值,该值由于指示希望应用于事件的事件行为。

    RoutedEventArgs类

    有些情况下,可能希望确定事件最初发生的位置。可从RoutedEventArgs类的属性获取这一信息以及其他细节

    处理挂起的事件

    有一个方法可接受被标记为处理过的事件。AddHandler方法提供了一个重载版本,可以用

    附加事件

    按钮有Click事件,而其他基类没有定义这个控件

    假设在StackPanel面板中封装了一堆按钮,并希望在一个事件处理程序中处理所有这些按钮的单击事件。以下代码是不可用的,因为StackPanel没有Click事件。

    <StackPanel Click="Dosomething" Margin="5">
        <Button Name="cmd1">Command 1</Button>
        <Button Name="cmd2">Command 2</Button>
        <Button Name="cmd3">Command 3</Button>
    </StackPanel>

    解决办法是:

    <StackPanel Button.Click="Dosomething" Margin="5">
         <Button Name="cmd1">Command 1</Button>
         <Button Name="cmd2">Command 2</Button>
         <Button Name="cmd3">Command 3</Button>
    </StackPanel>

    可在代码中关联附加事件,但需要使用UIElement.AddHandler方法

    为了确定是谁引发

    或者是对每个按钮设置Tag

                                 

    隧道路由事件

    隧道路由事件易于识别,都以单词Preview开头,而且WPF通常成对地定义冒泡路由事件和隧道路由事件。如果把隧道路由事件标记已经处理,就不会发生冒泡路由事件

    如果需要执行一些预处理(根据键盘上特定的键执行动作或过滤掉特定的鼠标动作),隧道事件还是很有用的

  • 相关阅读:
    配置好IIS中的SMTP服务器
    金秋十月
    "小生"的Google搜索结果
    "苏州大本营"腐败大会第三次顺利召开
    我修改了半年的密码还没有成功修改,dudu你能修改吗?
    好资源大家分享
    利用Google来调用其他网站查询信息
    推荐一本书<<专家门诊——ASP.NET开发答疑200问>>
    谁能给我一个FeedDemon v1.1的序列号或者注册文件
    毕业2月有余,苏州同学腐败第二次大聚会
  • 原文地址:https://www.cnblogs.com/yinghualuowu/p/9409788.html
Copyright © 2011-2022 走看看