《深入浅出WPF》学习笔记(四)——RoutedEvent

RoutedEvent

一、直接事件(CLR事件)

  事件的前身是消息(Message),Windows是消息驱动的操作系统(消息触发算法逻辑),运行在其上的程序也照此机制运行。微软将消息机制封装成了更易理解的时间模型:
在这里插入图片描述
  繁琐的消息驱动机制在事件模型中被简化为三个要素:

  • 事件拥有者: 消息的发送者,事件(event)被触发则消息被发送;
  • 事件响应者: 消息的接收、处理者,事件处理器(EventHandler)对事件做出响应;
  • 事件订阅关系: 使event和EventHandler关联起来;
    • 事件:使用enent关键字修饰的委托类成员变量;
    • 事件处理器:函数。

  这种模型中,事件的响应者通过订阅关系直接关联在事件拥有者事件上,这种模型称为直接事件模型或CLR事件模型。

以WPF中的Button为例:

/*
 * 以这里的按钮为例说明CLR事件模型的对应关系:
 * 事件拥有者:toPage1(按钮);
 * 事件:toPage1.Click;
 * 事件响应者:ContentControl(页面);
 * 事件处理器:ToPage1_Click方法(事件响应者通过事件处理器对事件作出响应);
 * 订阅关系:在MainWindow.g.cs文件中用如下语句确立订阅关系
 *          this.toPage1.Click += new System.Windows.RoutedEventHandler(this.ToPage1_Click);
*/
private void ToPage1_Click(object sender, RoutedEventArgs e)
{
   
    if (page1 == null)
    {
   
        page1 = new Page1();
    }
    PageView.Content = new Frame()
    {
   
        Content = page1
    };
}

  直接事件有两个弊端:

  • 每对消息是“发送→响应”关系,必须建立显式的点对点订阅关系;
  • 事件的宿主必须能够直接访问事件的响应者,不然无法建立订阅关系。

二、路由事件

路由事件与直接事件的区别
  • 直接事件激发时,发送者直接将消息通过事件订阅交送给事件响应者,响应者使用其事件处理器方法对事件的发生作出响应、驱动程序逻辑按客户需求运行;
  • 路由事件的时间拥有者和事件响应者之间没有直接显式的订阅关系事件拥有者只负责激发事件,并不关心由谁响应,而事件的响应者装有事件侦听器,针对某类事件进行侦听
路由事件沿逻辑树向上传递,按顺序响应!

编写书中例程验证路由事件的传递路径:

C#:

public partial class Built_in_RoutedEvent : Page
{
   
    public Built_in_RoutedEvent()
    {
   
        InitializeComponent();
        /*
         * 为gridRoot安装针对Button.Click事件的侦听器:
         * 安装侦听器有两种方法:
         * 一、在xaml中直接添加:如当前代码实现;
         *      在xaml中直接写方法:Button.Click/ButtonBase.Click = “方法名”;
         * 二、自定义:
         *      在窗体的构造器中调用gridRoot的AddHandler方法,把想监听的事件与事件处理器关联起来,自定义语句如下:
         * //this.gridRoot.AddHandler(Button.ClickEvent, new RoutedEventHandler(this.GridRoot_Click));
         * //this.gridA.AddHandler(Button.ClickEvent, new RoutedEventHandler(this.GridA_Click));
        */
    }
    //使用WPF内置路由事件
    #region
    //在xaml中用Button直接生成(没有自动提示)
    private void GridA_Click(object sender, RoutedEventArgs e)
    {
   
        MessageBox.Show("response by gridA");
    }
    //在xaml中用ButtonBase直接生成(有自动提示)
    private void GridRoot_Click(object sender, RoutedEventArgs e)
    {
   
        MessageBox.Show((e.OriginalSource as FrameworkElement).Name);
    }
    //自定义事件处理器
    //private void ButtonClicked(object sender, RoutedEventArgs e)
    //{
   
    //    MessageBox.Show((e.OriginalSource as FrameworkElement).Name);
    //}
    #endregion
}

xaml:

<Grid x:Name="gridRoot" Background="Lime" Grid.Column="0" Grid.Row="0"
            ButtonBase.Click="GridRoot_Click">
    <Grid x:Name="gridA" Margin="10" Background="Blue" Button.Click="GridA_Click">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Canvas x:Name="canvasLeft" Grid.Column="0" Background="Red" Margin="10">
            <Button x:Name="buttonLeft" Content="Left" Width
  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值