当前位置: 首页 > news >正文

《深入浅出WPF》读书笔记.8路由事件

《深入浅出WPF》读书笔记.8路由事件

背景

路由事件是直接响应事件的变种。直接响应事件,事件触发者和事件响应者必须显示订阅。而路由事件的触发者和事件响应者之间的没有显示订阅,事件触发后,事件响应者安装事件监听器,当事件传递到此时,事件处理器进行响应,并决定事件是否继续传递。

路由事件

WPF的两种树形结构

逻辑树

逻辑树就是UI树

可视元素树

单独组件的构成元素树

事件基础

路由事件

<Window x:Class="RouteEventDemo.RouteEventDemo1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:RouteEventDemo"mc:Ignorable="d"Title="RouteEventDemo1" Height="450" Width="600"><Grid x:Name="gridRoot" Background="LightSalmon" ButtonBase.Click="gridRoot_Click"><Grid x:Name="gridA"><Grid.ColumnDefinitions><ColumnDefinition Width="100*"></ColumnDefinition><ColumnDefinition Width="100*"></ColumnDefinition></Grid.ColumnDefinitions><Canvas Grid.Column="0"><Button x:Name="btn1" Width="100" Height="40" Content="leftButton" Canvas.Left="100" Canvas.Top="197"></Button></Canvas><Canvas Grid.Column="1"><Button x:Name="btn2" Width="100" Height="40" Content="rightButton" Canvas.Left="100" Canvas.Top="197"/></Canvas></Grid></Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;namespace RouteEventDemo
{/// <summary>/// RouteEventDemo1.xaml 的交互逻辑/// </summary>public partial class RouteEventDemo1 : Window{public RouteEventDemo1(){InitializeComponent();//this.gridRoot.AddHandler(Button.ClickEvent, new RoutedEventHandler(btn_Clicked));}private void btn_Clicked(object sender, RoutedEventArgs e){MessageBox.Show(string.Format("OriginalSource:{0},Source:{1}",(e.OriginalSource as FrameworkElement).Name,(e.Source as FrameworkElement).Name));}private void gridRoot_Click(object sender, RoutedEventArgs e){MessageBox.Show(string.Format("OriginalSource:{0},Source:{1}", (e.OriginalSource as FrameworkElement).Name, (e.Source as FrameworkElement).Name));}}
}

事件传递路线

自定义路由事件

自定义路由分三步

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;namespace RouteEventDemo
{public class TimeButton : Button{//声明注册路由事件public static readonly RoutedEvent ReportTimeEvent = EventManager.RegisterRoutedEvent("ReportTime", RoutingStrategy.Tunnel, typeof(EventHandler<ReportTimeEventArgs>), typeof(TimeButton));//CLR事件包装器public event RoutedEventHandler ReportTime{add { this.AddHandler(ReportTimeEvent, value); }remove { this.RemoveHandler(ReportTimeEvent, value); }}//激发路由事件protected override void OnClick(){//保证原有功能base.OnClick();ReportTimeEventArgs args = new ReportTimeEventArgs(ReportTimeEvent, this);args.ClickTime = DateTime.Now;this.RaiseEvent(args);}}
}
<Window x:Class="RouteEventDemo.UserDefinedRouteEventDemo"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:RouteEventDemo"mc:Ignorable="d"local:TimeButton.ReportTime="ReportTimeHandler"Title="UserDefinedRouteEventDemo" Height="450" Width="600"><Grid x:Name="grd1" local:TimeButton.ReportTime="ReportTimeHandler"><Grid x:Name="grd2" local:TimeButton.ReportTime="ReportTimeHandler"><Grid x:Name="grd3" local:TimeButton.ReportTime="ReportTimeHandler"><StackPanel x:Name="sp1" local:TimeButton.ReportTime="ReportTimeHandler"><ListBox x:Name="lb1" local:TimeButton.ReportTime="ReportTimeHandler"></ListBox><local:TimeButton local:TimeButton.ReportTime="ReportTimeHandler" Width="100" Height="40" Content="ReportTime"></local:TimeButton></StackPanel></Grid></Grid></Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;namespace RouteEventDemo
{/// <summary>/// UserDefinedRouteEventDemo.xaml 的交互逻辑/// </summary>public partial class UserDefinedRouteEventDemo : Window{public UserDefinedRouteEventDemo(){InitializeComponent();}private void ReportTimeHandler(object sender, ReportTimeEventArgs e){FrameworkElement frameworkElement = sender as FrameworkElement;if (frameworkElement != null){string timeStr = e.ClickTime.ToString();string content = string.Format("{0}到达{1}", timeStr, frameworkElement.Name);this.lb1.Items.Add(content);}//指定到某个元素停止if (frameworkElement.Name == "grd2"){e.Handled = true;}}}
}

OriginalSource和Source

Source:元素树

OriginalSource:可视化元素树

<UserControl x:Class="RouteEventDemo.UserControl1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:RouteEventDemo"mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="120"><Border BorderBrush="Orange" CornerRadius="3" BorderThickness="5"><Button x:Name="innerBtn" Content="OK"></Button></Border>
</UserControl>
<Window x:Class="RouteEventDemo.SourceDemo"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:RouteEventDemo"mc:Ignorable="d"Title="SourceDemo" Height="450" Width="800"><Grid x:Name="gd1"><local:UserControl1 x:Name="myUc" Margin="5"></local:UserControl1></Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;namespace RouteEventDemo
{/// <summary>/// SourceDemo.xaml 的交互逻辑/// </summary>public partial class SourceDemo : Window{public SourceDemo(){InitializeComponent();this.AddHandler(Button.ClickEvent, new RoutedEventHandler(btn_Clicked));}private void btn_Clicked(object sender, RoutedEventArgs e){MessageBox.Show(string.Format("OriginalSource:{0},Source:{1}", (e.OriginalSource as FrameworkElement).Name, (e.Source as FrameworkElement).Name));}}
}

附加事件

附加事件和路由事件的区别在于宿主是否为UI控件。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;namespace RouteEventDemo
{public class Student{public static readonly RoutedEvent NameChangedEvent = EventManager.RegisterRoutedEvent("NameChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Student));public static void AddNameChangedHandler(DependencyObject o, RoutedEventHandler h){UIElement element = o as UIElement;if (element != null){element.AddHandler(NameChangedEvent, h);}}public static void RemoveNameChangedHandler(DependencyObject o,RoutedEventHandler h){UIElement element = o as UIElement;if (element != null){element.RemoveHandler(NameChangedEvent, h);}}public string Name { get; set; }public int Id { get; set; }}
}
<Window x:Class="RouteEventDemo.AttachedEventDemo"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:RouteEventDemo"mc:Ignorable="d"Title="AttachedEventDemo" Height="450" Width="600"><Grid x:Name="grdMain"><Button x:Name="btn1" Content="点击一下" Width="120" Height="40" Click="btn1_Click"></Button></Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;namespace RouteEventDemo
{/// <summary>/// AttachedEventDemo.xaml 的交互逻辑/// </summary>public partial class AttachedEventDemo : Window{public AttachedEventDemo(){InitializeComponent();//this.grdMain.AddHandler(Student.NameChangedEvent, new RoutedEventHandler(StudentNameChangedEventHandler));Student.AddNameChangedHandler(this.grdMain, new RoutedEventHandler(StudentNameChangedEventHandler));}private void StudentNameChangedEventHandler(object sender, RoutedEventArgs e){MessageBox.Show((e.OriginalSource as Student).Id.ToString());}private void btn1_Click(object sender, RoutedEventArgs e){Student student = new Student() { Id = 1, Name = "Tom" };student.Name = "Tim";RoutedEventArgs args = new RoutedEventArgs(Student.NameChangedEvent,student);this.btn1.RaiseEvent(args);}}
}

git地址

GitHub - wanghuayu-hub2021/WpfBookDemo: 深入浅出WPF的demo

得加快学习速度了,记得点赞关注哦~👉⭐

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 使用pgrs在wsl中为postgres写拓展
  • huggingface.co 无法访问问题换源解决
  • c++修炼之路之C++11
  • Mac/Linux系统matplotlib中文支持问题
  • Java中类的成员介绍
  • 设计模式-结构性模式
  • Elasticsearch 里的父子文档插入和查询
  • upload-labs通关攻略
  • jetson orin nx安装todesk
  • Matlab三维图的坐标轴标签 自动平行坐标/自动旋转
  • Android耗电优化,如何定位问题,如何修改
  • Unity学习路线
  • vscode上传自己开发的npm包
  • 哈希表(模拟实现)
  • Linux基础指令(2)
  • 【剑指offer】让抽象问题具体化
  • 77. Combinations
  • JSONP原理
  • Js基础知识(一) - 变量
  • Less 日常用法
  • Promise面试题,控制异步流程
  • rc-form之最单纯情况
  • session共享问题解决方案
  • 计算机在识别图像时“看到”了什么?
  • 聊聊flink的BlobWriter
  • 使用putty远程连接linux
  • 物联网链路协议
  • 智能网联汽车信息安全
  • 自制字幕遮挡器
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (7) cmake 编译C++程序(二)
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (一)Java算法:二分查找
  • (自用)gtest单元测试
  • .Net core 6.0 升8.0
  • .NET Core 中插件式开发实现
  • .net core使用ef 6
  • .NET WPF 抖动动画
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • /etc/skel 目录作用
  • @SpringBootConfiguration重复加载报错
  • [ 常用工具篇 ] AntSword 蚁剑安装及使用详解
  • [ 云计算 | AWS 实践 ] Java 如何重命名 Amazon S3 中的文件和文件夹
  • [BT]小迪安全2023学习笔记(第15天:PHP开发-登录验证)
  • [BZOJ 1032][JSOI2007]祖码Zuma(区间Dp)
  • [BZOJ]4817: [Sdoi2017]树点涂色
  • [C++][STL源码剖析] 详解AVL树的实现
  • [CDOJ 838]母仪天下 【线段树手速练习 15分钟内敲完算合格】
  • [Cloud Networking] Layer 2
  • [C语言]-基础知识点梳理-编译、链接、预处理
  • [JavaWeb学习] tomcat简介、安装及项目部署