第一章 WPF概述

WPF(Windows Presentation Foundation)主要牛在 内置硬件加速分辨率无关

1.1 Windows图形演化

传统的Windows应用程序都依靠Windows操作系统的User32和GDI/GDI+来创建用户界面

User32:该部分为许多元素(如窗口、按钮和文本框等)提供了熟悉的Windows外观

GDI/GDI+:该部分为渲染简单形状、文本以及图像提供了绘制支持,但增加了复杂程度(而且通常性能很差)

新的解决方案:

DirectX:起初是一个易于出错的组合性质的工具包,用于在Windows平台上开发有效。DirectX主要关注速度,支持所有的主流显卡,用于游戏开发

WPF底层的图形技术是DirectX,意味着所有的绘图工作都是通过DirectX管线完成的,也支持硬件加速。

1.2 WPF高级API

WPF引入到Windows编程领域的一些最重要的变化

  • 类似 Web 的布局模型。与通过特定的坐标将控件固定在具体位置不同,WPF 十分注重灵活的流式布局,根据控件的内容灵活地排列控件,从而使用户界面能适应变化幅度大的内容以及不同的语言。
  • 丰富的绘图模型。与逐像素进行绘制不同,在 WPF 中可直接处理图元--基本形状、文本块以及其他图形元素。也可使用其他新特性,如真正的透明控件、放置多层并具有不同透明度内容的功能以及本地 3D支持。
  • 丰富的文本模型。WPF 为 Windows应用程序提供了在用户界面的任何位置显示丰富的样式化文本的功能。甚至可将文本和列表、浮动的图形以及其他用户界面元素结合起来。并且如果需要显示大量文本,还可使用高级的文档显示特性,例如换行、分列和对齐,以提高可读性。
  • 作为首要编程概念的动画。在 WPF 中,不必再用计时器来强制窗体重绘自身。与此相反,动画成为 WPF 框架的固有部分。在 WPF 中可使用声明式标签定义动画,WPF 会自动让它们运动起来。
  • 支持音频和视频媒体。以前的用户界面开发工具包(如 Windows 窗体)对多媒体的处理有很大的限制。但 WPF 支持播放任何 Windows 媒体播放器所支持的音频和视频文件,并允许同时播放多个媒体文件。更引人注目的是,WPF提供了允许在用户界面的其他部分集成视频内容的工具,还允许添加特效技巧,比如在一个旋转的 3D 立方体上放置视频窗口。
  • 样式和模板。通过样式可实现显示格式的标准化,并可在整个应用程序中反复使用通过模板可改变元素的渲染方式,甚至改变核心控件(如按钮)的渲染方式。在创建现代的具有皮肤的用户界面时,从来都不像现在这样方便。
  • 命令。大多数用户已认识到,通过菜单或工具栏触发 Open 命令并没什么区别,最终结果是相同的。现在通过代码抽象,可在特定位置定义应用程序命令并将其链接到多个控件上。
  • 声明式用户界面。尽管可编写代码来创建WPF窗口,但VisualStudio提供了另一种方式。它将每个窗口的内容串行化到XAML文档中的一组XML标签中。其优点是用户界面和代码完全分离,并且图形设计人员可使用专业工具编辑XAML文件,并最终润色应用程序的前端界面。XAML是可扩展应用程序标记语言(可扩展应用程序标记语言)的缩写,第2章将详细介绍XAML的相关内容。
    基于页面的应用程序。可使用 WPF 创建类似于浏览器的应用程序,此类应用程序可通过"前进"和"后退"导航按钮在一组页面中移动。由 WPF 来处理那些纷繁的细节,如页面历史。甚至可将项目部署为运行于正中的基于浏览器的应用程序。

1.3 分辨率无关

假设你画了一个 1 厘米宽的按钮。

  • 如果用传统的像素固定方式(比如早期的 WinForm),它会强制用 "100 个像素" 来画这个按钮。
    • 在低分辨率屏幕(比如 1366×768,像素比较 "大")上,100 像素刚好是 1 厘米,看起来正常。
    • 但在高分辨率屏幕(比如 4K,像素很 "小")上,100 像素可能只有 0.5 厘米,按钮会变得特别小,甚至看不清文字。

而 WPF 的 "分辨率无关" 就不一样了:

它用的是 "虚拟像素"(叫设备独立像素),这个虚拟像素会自动适配屏幕的清晰度。

比如你设定按钮是 "1 厘米宽",WPF 会根据屏幕的实际分辨率算:

  • 低分辨率屏幕:可能用 100 个实际像素来画,刚好 1 厘米。
  • 高分辨率屏幕:可能用 200 个实际像素来画(因为像素小),但实际宽度还是 1 厘米,而且因为用了更多像素,画面更清晰,不会模糊。

所以核心就是:WPF 的界面元素会 "智能" 适配屏幕的清晰度,不管屏幕是模糊还是清晰,元素的实际大小(你眼睛看到的物理尺寸)基本不变,而且始终清晰,不用你手动改尺寸适配不同屏幕。

若计算出是小数,WPF会通过反锯齿特性进行处理

1.4 WPF体系结构

  • PresentationFramework.d 包含 WPF 顶层的类型,包括那些表示窗口、面板以及其他类型控件的类型。它还实现了高层编程抽象,如样式。开发人员直接使用的大部分类都来自这个程序集。

  • PresentationCore.d 包含了基础类型,如 UIElement 类和 Visual类,所有形状类和控件类都继承自这两个类。如果不需要窗口和控件抽象层的全部特征,可使用这一层,而且仍能利用 WPF 的渲染引擎。

  • WindowsBase.d 包含了更多基本要素,这些要素具有在 WPF 之外重用的潜能,如DispatcherObject 类和 DependencyObject 类,这两个类引入了依赖项属性(详见第4章)。

  • milcore.dll 是 WPF 渲染系统的核心,也是媒体集成层(Media Integration Layer,MIL)的基础。其合成引擎将可视化元素转换为Direct3D 所期望的三角形和纹理。尽管将milcore.dll 视为 WPF 的一部分,但它也是 Windows Vista和 Windows 7的核心系统组件之一。实际上,桌面窗口管理器(Desktop Window Manager,DWM)使用 milcore.dll渲染桌面。

    • milcore.d 有时称为"托管图形"引擎。与公共语言运行库(CLR)管理.NET 应用程序的生命期非常类似,milcore.dll 管理显示状态。而且正如有了CLR,开发人员不再为释放对象和回收内存而感到烦恼一样,milcore.dl 让开发人员不必再考虑使窗口无效和重绘窗口。只需使用希望显示的内容创建对象即可,当拖动窗口、窗口被覆盖和显露、最小化窗口和还原窗口时,由 milcore.dll负责绘制窗口的恰当部分。
  • WindowsCodecs.d 是一套提供图像支持的低级 API(例如处理、显示以及缩放位图和JPEG 图像)。

  • Direct3D 是一套低级 API,WPF 应用程序中的所有图形都由它进行演染。

  • User32 用于决定哪些程序实际占有桌面的哪一部分。所以它仍被包含在 WPF 中,但不再负责渲染通用控件。

WPF中的所有绘图内容都由Direct3D渲染,甚至二维图形和普通文本也被转换为三角形并被传送到Direct3D管线,而并不使用GDI+或User32渲染图形

1.4.1 类层次结构

WPF 核心名称空间以System.Windows开头(如 System.Windows、System.Windows.Controls以及 System.Windows.Media)。唯一例外是由 System.Windows.Forms 开头的名称空间,它们是Windows 窗体工具包的一部分。

  • System.Threading.DispatcherObject 类

    • WPF应用程序使用为人熟知的单线程亲和 (Simgle-Thread Afinity,STA)模型,这意味着整个用户界面由单个线程拥有。从另一个线程与用户界面元素进行交互是不安全的。为方便使用此模型,每个 WPF 应用程序由协调消息(键盘输入、鼠标移动乃至框架处理,如布局)的调度程序管理。通过继承自 DispatcherObject类,用户界面中的每个元素都可以检査代码是否在正确的线程上运行,并能通过访问调度程序为用户界面线程封送代码。在第31章将介绍有关 WPF 线程模型的更多内容。
  • System.Windows.DependencyObject 类

    • 在 WPF 中,主要通过属性与屏幕上的元素进行交互。在早期设计阶段,WPF 的设计者决定创建一个更加强大的属性模型,该模型支持许多特性,例如更改通知、默认值继承以及减少属性存储空间。最终结果就是依赖项属性(dependency property)特性,第4章将分析该特性。通过继承自DependencyObject类,WPF 类可获得对依赖项属性的支持。
  • System.Windows.Media.Visual 类

    • 在 WPF 窗口中显示的每个元素本质上都是 Visual 对象。可将 Visual 类视为绘图对象,其中封装了绘图指令、如何执行绘图的附加细节(如剪裁、透明度以及变换设置)以及基本功能(如命中测试)。Visual类还在托管的 WPF 库和渲染桌面的 milcore.d 程序集之间提供了链接。任何继承自 Visual 的类都能在窗口上显示出来。如果更愿意使用轻量级的 API创建用户界面,而不想使用 WPF 的高级框架特征,可使用第 14 章中描述的方法,直接对 Visual对象进行编程。
  • System.Windows.UlElement 类

    • UIElement 类增加了对 WPF 本质特征的支持,如布局、输入、焦点和事件(WPF 团队使用首字母缩写词 LIFE 来表示)。例如,这里定义两个步骤的测量和排列布局过程,这些内容将在第 18章中介绍。在该类中,原始的鼠标单击和按键操作被转换为更有用的事件,如 MouseEnter事件。与属性类似,WPF 实现了增强的称为路由事件 (routed event)的事件路由系统。第5章将讲述路由事件的工作原理。最后,UIElement类中还添加了对命令的支持(详见第9章)。
  • System.Windows.FrameworkElement 类

    • FrameworkElement 类是 WPF 核心继承树中的最后一站。该类实现了一些全部由 UIElement类定义的成员。例如,UIElement 类为 WPF 布局系统设置了基础,但 FrameworkElement 类提供了支持它的重要属性(如 HorizontalAlignmentMargin 属性)。UIElement 类还添加了对数据绑定、动画以及样式等核心特性的支持。
  • System.Windows.Shapes.Shape 类

    • 基本的形状类(如 Rectangle 类、Polygon 类、Ellipse 类、Line 类以及 Path 类)都继承自该类。可将这些形状类与更传统的 Windows 小组件(如按钮和文本框)结合使用。在第 12 章将开始介绍如何构建形状。
  • System.Windows.Controls.Control 类

    • 控件(control)是可与用户进行交互的元素。控件显然包括 TextBox 类、Button 类和 ListBox类等。Control类为设置字体以及前景色与背景色提供了附加属性。但最令人感兴趣的细节是模板支持 ,通过模板支持,可使用自定义风格的绘图替换控件的标准外观。第17 章将介绍控件模板。
      • 在 Windows 窗体编程中,窗体中的每个可视化项都称为控件。
      • 在 WPF 中,情况不再如此。可视化内容被称为元素 (element),只有部分元素是控件(控件是那些能够接收焦点并能与用户进行交互的元素)。更令人费解之处在于,许多元素是在 System.Windows.Controls 名称空间中定义的,但它们不是继承自 System.Windows.Controls.Control类,并且不被认为是控件。Panel 类便是其中一例。
  • System.Windows.Controls.ContentControl 类

    • ContentControl 类是所有具有单一内容的控件的基类,包括简单的标签乃至窗口的所有内容。该模型给人印象最深刻的部分是:控件中的单一内容可以是普通字符串乃至具有其他形状和控件组合的布局面板(详见第6章)。
  • System.Windows.Controls.ltemsControl 类

    • ItemsControl 类是所有显示选项集合的控件的基类 ,如 ListBoxTreeView 控件。列表控件十分灵活
    • 例如,使用 ItemsControl类的内置特征,可将简单的 ListBox 控件变换成单选按钮列表、复选框控件列表、平铺的图像或是您所选择的完全不同的元素的组合。实际上,WPF中的菜单、工具栏以及状态栏都是特定的列表,并且实现它们的类都继承自 ItemsContorl 类。在第 19章中学习数据绑定时,将开始使用列表控件。在第 20 章中将进一步学习列表控件,第22 章将介绍最专业的列表控件。
  • System.Windows.Controls.Panel 类

    • Panel类是所有布局容器的基类布局容器是可包含一个或多个子元素、并按特定规则对子元素进行排列的元素。这些容器是 WPF布局系统的基础,要以最富有吸引力、最灵活的方式安排内容,使用这些容器是关键所在。在第3章将详述WPF 布局系统。

1.5 小结

  • 硬件加速。通过 DirectX 执行所有 WPF 绘图操作,以便充分利用现代显卡的最新功能。
  • 分辨率无关性。WPF 能够根据系统DPI设置,非常灵活地放大和缩小显示的内容,以使其适合所用的显示器和显示选择。
  • 控件无固定外观。在传统的 Windows 开发中,在定制的符合需求的控件(此类控件是指自绘制的控件)和由操作系统渲染的本质上外观固定的控件之间存在很大的差别。在WPF 中,从基本的 Rectangle 形状到标准的 Button 控件或更复杂的 Toolbar 控件,都是使用相同的渲染引擎绘制的,并且都是完全可定制的。因此,WPF控件经常被称为无外观控件--它们为控件定义了功能,但没有固定"外观"
  • 声明式用户界面。第2章将介绍 XAML,XAML 是用于定义 WPF 用户界面的标记标准。通过 XAML,不必编写代码即可创建窗口。特别是XAML的能力不局限于创建成不变的用户界面。可以使用许多工具,如数据绑定和触发器等自动运行基本的用户界面行为(例如,当页面通过记录源时文本框更新自身,当鼠标移动到标签上时标签变亮),所有这些都不需要编写 C#代码。
  • 基于对象的绘图。即使准备在更低级的可视化层(而非高级元素层)上工作,也不需要使用绘图和像素进行工作,而是创建图形对象并让 WPF 尽可能最优化地显示出来。
相关推荐
necessary6531 天前
从工行“余额归零”事件看CAP定理:当金融系统在一致性与可用性之间做出选择
分布式·金融·wpf·可用性测试
棉晗榜1 天前
WPF隐藏控件后,怎么让其上部的控件空间自动撑高
wpf
壹佰大多2 天前
【Redisson分布式锁源码分析-3】
数据结构·分布式·mysql·spring·spring cloud·wpf·lua
LateFrames2 天前
以小白视角尝试 WPF / WinUI3 / MAUI / MAUI Blazor 构建 Windows 桌面程序
windows·wpf·maui·mauiblazor·winui3
偶尔的鼠标人3 天前
Avalonia/WPF 打开子窗口,并且跨页面传值
c#·wpf·mvvm·avalonia
玖笙&3 天前
✨WPF编程进阶【6.1】:图形原则(附源码)
c++·c#·wpf·visual studio
lixy5793 天前
WPF检测网络状态切换
wpf
纸照片3 天前
WPF中为Button设置IsMouseOver和IsPressed事件中改变背景颜色不起作用
c#·.net·wpf
Aevget3 天前
DevExpress WPF中文教程:Data Grid - 如何使用虚拟源?(四)
ui·.net·wpf·devexpress·wpf控件