《2022年WPF基础教程之体系结构 .pdf》由会员分享,可在线阅读,更多相关《2022年WPF基础教程之体系结构 .pdf(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、WPF 基础教程之体系 结构本主题提供 Windows Presentation Foundation(WPF)类层次结构的指 导教程,涵盖了 WPF 的大部分主要子系 统,并描述它们是如何交互的。本主 题还详细 介绍了WPF 架构师所做的一些 选择。System.Object WPF 主要编程模型是通 过托管代 码公开的。在 WPF 的早期 设计阶段,曾有过大量关于如何界定系 统的托管 组件和非托管 组件的争 论。CLR 提供一系列的功能,可以令开发效率更高并且更加可靠(包括内存管理、错误处 理和通用 类型系统等),但 这是需要付出代价的。下图说明了 WPF 的主要 组件。关系图的红色部分(
2、PresentationFramework、PresentationCore 和 milcore)是WPF 的主要代 码部分。在这些组件中,只有一个是非托管 组件 milcore.milcore 是以非托管代 码编写的,目的是实现与 DirectX 的紧密集成。WPF 中的所有 显示是通 过 DirectX 引擎完成的,可实现 高效的硬件和软件呈现。WPF 还要求对内存和 执行进行精确控制。milcore 中的组合引擎受性能影响 关系大,需要放弃 CLR 的许多优点来提高性能。名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 8 页 -本主题的后面部分将 讨论 WPF 的托管和非托
3、管部分之 间的通信。下面介绍托管编程模型的其余部分。System.Threading.DispatcherObject WPF 中的大多数 对象是从DispatcherObject 派生的,这提供了用于 处理并发和线程的基本构造。WPF 基于调度程序 实现的消息系 统。其工作方式与常 见的 Win32 消息泵非常类似;事 实上,WPF 调度程序使用User32 消息执行跨线程调用。要讨论 WPF 中的并 发,首先必须真正理解两个核心概念调度程序和 线程关联。在 WPF 的设计阶 段,目标趋向于单一线程的执行,但这不是一种与线程“关联的”模型。当一个 组件使用 执行线程的标识来存储某种类型的状
4、态时,将 发生线程关联。最常见的形式是使用 线程本地存储(TLS)来存储状态。线程关联要求执行的每个逻辑线 程仅由操作系 统中的一个物理 线程所拥有,这将占用大量内存。最后,WPF 的线程处理模型保持与具有 线程关联的单一线程执行的现有 User32 线程处理模型同 步。主要原因是互操作性类似于 OLE 2.0 的系统、剪 贴板和Internet Explorer 均需要 单一线程关联(STA)执行。假设您具有 带有 STA 线程的对象,则需要一 种方式来在 线程之间通信,并验证您是否位于正确的 线程上。调度程序的作用就在于此。调度程序是一个基本的消息调度系统,具有多个按优先级排列的 队列。消
5、息的示例包括原始 输入通知(鼠标移动)、框架函数(布局)或用户命令(执行此方法)。通 过从 DispatcherObject 派生,您可以创建一个具有STA 行为的 CLR 对象,并在创建时获得一个指向 调度程序的指 针。System.Windows.DependencyObject 生成 WPF 时使用的主要体系 结构原理之一是首 选属性而不是方法或事件。属性是声明性的,使您更方便地指定意 图而不是操作。它还支持模型 驱动或数据 驱动的系统,以 显示用户界面内容。这种理念的 预期效果是 创建您可以 绑定到的更多属性,从而更好地控制 应用程序的行 为。为了从由属性 驱动的系统获得更多,需要一个
6、比CLR 提供的内容更丰富的属性系统。此丰富性的一个 简单示例就是更改通知。为了实现双向绑定,您需要绑定的双方支持更改通知。为了使行 为与属性 值相关联,您需要在属性值更改时得到通知。Microsoft.NET Framework 具有一个INotifyPropertyChange 接口,使对象可以发布更改通知(不过,这是可选的)。名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 8 页 -WPF 提供一个丰富的属性系 统,该属性系 统是从 DependencyObject 类型派生的。该属性系 统实际 是一个“依赖”属性系 统,因 为它会跟踪属性表达式之 间的依赖关系,并在依赖关
7、系更改 时自动重新验证属性值。例如,如果您具有一个会继承的属性(如 FontSize),当 继承该值的元素的父 级发生属性更改 时,会自动更新系 统。WPF 属性系 统的基 础是属性表达式的概念。在WPF 的第一版中,属性表达式系统是关闭的,表达式都是作 为框架的一部分提供的。表达式致使属性系统不具有硬编码的数据 绑定、样式调整或继承,而是由框架内后面的 层来提供 这些功能。属性系 统还提供属性 值的稀疏存 储。因 为对象可以有数十个(如果达不到上百个)属性,并且大部分值处于其默 认状态(被 继承、由样式设置等),所以并非 对象的每个实例都需要具有在 该对象上定 义的每个属性的完全 权重。属性
8、系 统的最后一个新功能是附加属性的概念。WPF 元素是基于 组合和组件重用的原 则生成的。某些包含元素(如 Grid 布局元素)通常需要子元素上的其他数据才能控制其行 为(如行/列信息)。仸何 对象都可以 为仸何其他 对象提供属性定 义,而不是要将所有 这些属性与 每个元素相 关联。这与JavaScript 中的“expando”功能相似。System.Windows.Media.Visual 定义一个系 统后,下一步是将像素 绘制到屏幕上。Visual 类用于生成可 视化对象的树,每个对象可以 选择性地包含 绘制指令以及有 关如何呈 现这些指令(剪辑、变换等)的元数据。Visual 设计为
9、极其轻量且灵活,所以大部分功能未 进行 API 公开,并且极为依赖受保护的回调函数。Visual 实际上是到 WPF 组合系统的入口点。Visual 是以下两个子系 统之间的连接点:托管 API 和非托管milcore.WPF 通过遍历由 milcore 管理的非托管数据结构来显示数据。这些结构(称 为组合节点)代表 层次结构显示树,其中每个节点都有呈现指令。只能通过消息传递协议来访问此树(下 图右侧所示)。当对 WPF 编程时,您将创建 Visual 元素及派生的 类型,它们通过此消息 传递协议在内部与此 组合树进行通信。WPF 中的每个 Visual 可以不 创建组合节点,也可以创建一个或
10、多个 组合节点。名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 8 页 -请注意一个非常重要的体系 结构细节 可视对象和绘制指令的整个 树都要进行缓存。在图形方面,WPF 使用一个保留的呈 现系统。这可以使系 统以一个高刷新率重 绘系统,并且不会发生组合系统阻止对用户代码的回调。这有助于防止出 现应用程序无响应的情况。关系图中不十分引人注意的另一个重要细节是系统实际 上如何 执行组合。在 User32 和 GDI 中,系统是在一个即 时模式剪 辑系统上工作。当需要呈 现一个组件时,系 统会建立一个剪 辑边界,不允许组件接触 该边界之外的像素,然后会要求此 组件在该框中绘制像素。此
11、系统在内存受限的系 统上工作良好,因为当某些内容更改 时,只需要处理受影响的 组件即可 不会有两个 组件对一个像素的 颜色更改起作用。WPF 使用“绘画器的算法”绘制模型。这意味着并不是剪 辑每个组件,而是要求从显示内容的背面至正面来呈现每个组件。这允许每个组件在先前的 组件的显示内容上 绘制。此模型的优点是您可以生成部分透明的复杂形状。与现今的现代图形硬件比 较,此模型相对要快(创建 User32/GDI 的情况除外)。如上面所述,WPF 的一个核心原理是移 动到一个更具声明性且“以属性 为核心”的编程模型。在可视化系统中,这会表现为需要关注的两 种情况。名师资料总结-精品资料欢迎下载-名师
12、精心整理-第 4 页,共 8 页 -首先,如果您考虑保留的模式 图形系统,则实际 上是从命令性DrawLine/DrawLine 类型模型移 动到面向数据的模型new Line()/new Line()。通过这一向数据 驱动的呈现移动,可以在使用属性表达的 绘制指令上 进行复杂的操作。从 Drawing 派生的 类型实际上是用于呈 现的对象模型。第二,如果评估动画系统,您将看到它几乎是完全声明性的。无需要求 开发人员计算下一位置或下一 颜色,您可以将动画表示 为动画对象上的一 组属性。于是,这些动画可以表示 开发人员或设计人员的意图(在5 秒内将此按 钮从一个位置移 动到另一个位置),系 统就
13、可以确定完成此仸 务的最有效方式。System.Windows.UIElement UIElement 定义核心子系 统,包括 Layout、Input 和 Event。Layout 是 WPF 中的一个核心概念。在 许多系统中,可能有一组固定的布局模型(HTML 支持三 种布局模型:流、绝对和表),也可能没有布局模型(User32 实际仅支持绝对定位)。WPF 先假设开发 人员和设计人员希望有一个灵活的可 扩展布局模型,该模型可能是由属性 值而不是命令性 逻辑驱动 的。在 UIElement 级别,会引入布局的基本 协定-具有 Measure 和 Arrange 处理过程的两 阶段模型。Me
14、asure 允许组件确定它要采用的大小。此 阶段独立于Arrange,因为在许多情形下,父元素会要求子元素 测量若干次以确定其最佳位置和大小。父元素要求子元素测量这一事实体现了 WPF 的另一 关键原则 内容大小。WPF 中的所有控件支持 调整到内容原始大小的功能。这使本地化更加容易,并允 许在调整大小 时对元素进行动态布局。Arrange 阶段允许父元素定位并确定 每个子元素的最 终大小。通常会花 费大量的 时间来讨论 WPF 的输出端(Visual 及其相 关对象)。然而,在输入端也有 许多创新。WPF 输入模型的最基本更改也 许是一致模型,输入事件通过系统借助此模型 进行路由。输入是作
15、为内核模式 设备驱动 程序上的信号 发出的,并通过涉及 Windows 内核和 User32 的复杂进 程路由到正确的 进程和线程。与输入相对应的 User32 消息一旦路由到WPF,它就会转换为 WPF 原始输入消息,并发送到调度程序。WPF 允许原始输入事件 转换为 多个实际事件,允许在保证传递 到位的情况下在 较低的系统级别实现类 似“MouseEnter”的功能。每个输入事件至少会 转换为 两个事件“预览”事件和 实际事件。WPF 中的所名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 8 页 -有事件都具有通 过元素树路由的概念。如果事件从目 标向上遍 历树直到根,则被称
16、为“冒泡”,如果从根 开始向下遍 历到目标,它 们被称为“隧道”。输入预览事件隧道,使树中的仸何元素都有机会 筛选事件或 对事件采取操作。然后,常规(非 预览)事件将从目 标向上冒泡到根。分割隧道和冒泡 阶段使快捷 键等功能在 复合世界中表 现一致。在 User32 中,您可以通 过使用一个全局表来 实现快捷键,该表中包含您希望支持的所有快捷键(Ctrl+N 映射为“新建”)。在应用程序的 调度程序中,您可以 调用TranslateAccelerator,它会探查 User32 中的输入消息,并确定是否有仸何消息与已注册的快捷 键匹配。在 WPF 中,上述内容不会起作用,因 为系统是完全“可
17、组合”的 仸何元素都可以 处理和使用仸何快捷 键。将 这个两阶段模型用于 输入,将允许组件实现其自己的 TranslateAccelerator.为了进一步深化此功能,UIElement 还引入了 CommandBindings 的概念。WPF 命令系 统允许开发 人员以命令 终结点(一 种用于实现 ICommand 的功能)的方式定义功能。命令绑定使元素可以定 义输入笔势(Ctrl+N)和命令(“新建”)之间的映射。输入笔势和命令定 义都是可 扩展的,并且可以在使用 时联系到一起。这使得一些操作(例如,允许最终用户自定义其要在 应用程序内使用的 键绑定)显得无关紧要。至此,本主题已重点 讨论
18、了 WPF 的“核心”功能-PresentationCore 程序集中实现的功能。当生成 WPF 时,基 础部分(例如带有 Measure 和 Arrange 的布局的协定)和框架部分(例如 Grid 的特定布局的 实现)之 间的明确划分是希望的 结果。目标就是提供在堆 栈中处于较低位置的可 扩展性点,这将允许外部开发人员可以在需要 时创建自己的框架。System.Windows.FrameworkElement 可以按两 种不同的方式来看待FrameworkElement.它对在 WPF 的较低层中的子系统引入一 组策略和自定 义项。它 还引入了一 组新的子系 统。FrameworkElem
19、ent 引入的主要策略是 关于应用程序布局。FrameworkElement 在 UIElement 引入的基本布局 协定之上生成,并增加了布局“插槽”的概念,使布局制作者可以方便地 拥有一组面向属性的一致的布局 语义。HorizontalAlignment、VerticalAlignment、MinWidth 和 Margin 等属性使得从FrameworkElement 派生的所有组件在布局容器内具有一致的行为。利用 FrameworkElement,WPF 的核心 层中具有的 许多功能可以更方便地 进行名师资料总结-精品资料欢迎下载-名师精心整理-第 6 页,共 8 页 -API 公开。
20、例如,FrameworkElement 通过 BeginStoryboard 方法提供 对动画的直接访问。Storyboard 提供一 种针对 一组属性为多个动画编写脚本的方式。FrameworkElement 引入的两个最 关键的内容是数据 绑定和样式。曾经使用 Windows 窗体或 ASP.NET 创建应用程序用 户界面(UI)的用户应当对 WPF 中的数据 绑定子系 统较为 熟悉。在上述每个系统中,可通过一种简单 的方式来表达您希望将 给定元素中的一个或多个属性绑定到一个数据片断。WPF 对属性绑定、变换和列表 绑定提供全面支持。WPF 中数据 绑定的最 值得关注的功能之一是引入了数据
21、模板。利用数据模板,您可以声明性地指定某个数据片断的可视化方式。您可以将 问题换 个方向,让数据来确定将要 创建的显示内容,而无需创建可绑定到数据的自定 义用户界面。样式实际上是轻量级的数据 绑定。使用样式,您可以将共享定 义的一组属性绑定到元素的一个或多个 实例。通过显式引用(通过设置 Style 属性)或通过将样式与元素的CLR 类型隐式关联,便可以将样式应用到元素。System.Windows.Controls.Control 控件的最重要的功能是模板化。如果您将WPF 的组合系统视为 一个保留模式呈现系统,则控件可通 过模板化以一 种参数化的声明性方式描述其呈现。ControlTemp
22、late 实际上不过是一个用于 创建一组子元素的脚本,同 时绑定到由控件提供的属性。Control 提供一 组常用属性,如 Foreground、Background、Padding 等,模板创作者可以使用 这些常用属性来自定 义控件的 显示。控件的实现提供了数据模型和交互模型。交互模型定 义了一组命令(如窗口的“关闭”),以及到输入笔势的绑定(如 单击窗口上角的 红叉)。数据模型提供了一组属性,用于自定义交互模型或自定义显示(由模板确定)。数据模型(属性)、交互模型(命令和事件)及显示模型(模板)之 间的划分,使用户可以对控件的外 观和行为进行完全自定 义。最常见的控件数据模型是内容模型。如
23、果 查看 Button 之类的控件,您会看到它具有一个 类型为 Object 的名为“Content”的属性。在 Windows 窗体和ASP.NET 中,此属性通常 为一个字符串不过,这会限制您可以在按 钮中输入的名师资料总结-精品资料欢迎下载-名师精心整理-第 7 页,共 8 页 -内容类型。按钮的内容可以是 简单的字符串、复杂的数据 对象或整个元素 树。如果是数据 对象,可以使用数据模板构造 显示内容。摘要WPF 旨在帮助您 创建动态的数据 驱动的演示系 统。系 统的每一部分均可通 过驱动行为的属性集来 创建对象。数据绑定是系 统的基础部分,在每一层中均进行了集成。传统的应用程序 创建一个 显示内容,然后绑定到某些数据。在 WPF 中,关于控件的所有内容、显示内容的所有方面都是由某种类型的数据 绑定生成的。通过在按钮内部创建复合控件并将其 显示绑定到按 钮的内容属性,就会 显示按钮内的文本。当开始开发基于 WPF 的应用程序 时,您 应对 其感到非常熟悉。在其中 设置属性、使用对象和数据 绑定的方式与您使用Windows 窗体或 ASP.NET 是极其相似的。如果对 WPF 体系结构有更深的了解,您就能 够创建更丰富的 应用程序,这些应用程序在根本上会将数据 视为应 用程序的核心 驱动力。名师资料总结-精品资料欢迎下载-名师精心整理-第 8 页,共 8 页 -