WPF 开发人员需要知道的一切
21 – WPF 控件示例
在 WPF 中,控件是可以放置在窗口或页面上的可视组件。 下面仅举几个常见 WPF 控件的示例,重点介绍用户与之交互的主要控件。
Button – 单击按钮执行操作
CheckBox
RadioButton and GroupBox – 从一组中选择一个选项
Label – 基本标签
Tooltip – 当用户将鼠标悬停在控件上时,提供有关控件的更多信息
Expander – 用户单击扩展器以查看子控件,然后再次单击以隐藏它们
ComboBox – 从列表中选择一项
ListBox – 从列表中选择一项或多项
ListView – 列表项组,支持相同项的不同视图
TabControl – 每个选项卡都包含一组控件
DataGrid – 数据项的网格,通常绑定到数据源
TreeView – 层次树
TextBox – 可编辑文本
Slider – 滑动设置不同的值
ProgressBar – 显示进度
DatePicker – 选择日期
22 – 布局控制
在 WPF 中,控件布局的主要模型是基于流的,而不是基于坐标的。子控件添加到布局容器控件中,布局容器控件根据容器的大小和形状管理子控件的位置和大小。
以下是 WPF 中包含的主要布局控件:
- Canvas – 基于坐标的布局容器
- DockPanel – 控件与容器的一个边缘对齐(例如顶部/底部/左侧/右侧/填充)
- Grid – 位于行和列中的控件。 (空 WPF 应用程序中的默认顶级控件)
- StackPanel – 水平或垂直堆栈中的控件
- UniformGrid – 控件位于网格中,其中所有单元格的大小都相同
- VirtualizingStackPanel – 在水平或垂直堆栈中排列控件。显示的控件是较大项目列表中的一个可见子集。根据需要加载控件,即当它们变得可见时。
- WrapPanel – 控件放置在单行上,从左到右,然后根据需要换行到下一行。也可以从上到下,换到下一列。
23 – WPF 单位
在 Windows 窗体中,控件大小是使用像素指定的。在 WPF 中,大小是使用 WPF 单位指定的。
1 WPF 单位 = 1/96 英寸。
这意味着在 96 dpi(典型)下,1 WPF 单位 = 1 像素。 但这意味着在 120 dpi 时,1 WPF 单位 = 1.25 像素。 (120/96) 因为 WPF GUI 中的所有内容都使用 WPF 单位进行大小调整,所以所有控件都根据系统 DPI 正确调整大小。这样做的原因是它们在碰巧具有更高像素密度 (DPI) 的设备上看起来具有相同的物理尺寸。 96 单位按钮在 96 dpi 设备上为 1 英寸宽,在 120 dpi 设备上为 1 英寸宽(因为它可以放大到 120 像素)。
可以使用窗体的 AutoScaleMode 属性在 Windows 窗体中完成相同的缩放。但在 WPF 中,它是自动的。
完整公式:
#pixels = (# WPF Units) * (DPI / 96)
24 – 不要在 WPF 应用程序中使用位图
由于 WPF 能够根据系统 DPI 缩放应用程序,因此应避免在应用程序中使用位图。相反,您应该渲染所有控件,例如工具栏上的按钮,带有矢量图形,以便它们可以放大/缩小,但看起来仍然正确。
此过程中最困难的部分是找到要在您的应用程序中使用的基于矢量的图形图像,然后将它们转换为 XAML,以便您可以在 WPF 项目中使用它们。
Mike Swanson 为 Adobe Illustrator 编写了一个插件,允许将基于矢量的图像导出到 XAML(然后您可以将其直接导入到 WPF 项目中)。还有一篇很好的文章在这里解释了这个过程。
这是一个示例,显示了当应用程序窗口缩放时缩放的地球图像。
25 – 数据绑定概述
数据绑定是 WPF 的核心功能。在典型的应用程序中,有一个表示层,其中包含允许用户与应用程序及其数据交互的可视控件。表示层下方通常是业务层,其中包含包含实际数据的 CLR 对象。 (也可能有一个较低的数据层来保存数据,例如数据库)。
当用户使用应用程序时,期望:
- 当 CLR对象中的数据发生变化时,这些变化会反映在 GUI 中
- 当用户通过 GUI更改数据时,更改将复制到 CLR对象中
WPF 中的数据绑定模型通过 Binding 对象将 CLR 对象的属性绑定到用户界面控件来自动化这种关系。
26 – WPF 架构
下图显示了主要 WPF DLL 之间的依赖关系。 (点击图片查看全尺寸)。
以下是此图中列出的 DLL 的快速概览:
- System.Windows.Presentation.dll – 包含一些与加载项相关的类型
- PresentationFramework.Aero.dll - 为 WPF 控件实现 Aero 主题
- PresentationFramework.Classic.dll - 为 WPF 控件实现经典主题
- PresentationFramework.dll – 包含大部分主要的 WPF 控件,以及对数据绑定的支持
- PresentationUI.dll – 包含一些与主题相关的资源和
- System.Windows.Documents 的一些支持类
- ReachFramework.dll – 包含与打印和 XPS 文档相关的类型
- System.Printing.dll –包含与打印相关的主要类型
- PresentationCore.dll – 用于视觉呈现的低级类型,如 UIElement。也支持拖放。
- System.Windows.Input.Manipulations.dll – 输入操纵器的实现
- UIAutomationProvider.dll – 支持 UI 自动化(用于辅助功能)
- WindowsBase.dll – 低级类型,如DependencyObject 和DependencyProperty
- UIAutomationTypes.dll – 与 UI自动化相关的基本类型
27 – 类层次结构
在 WPF 中使用各种类和控件时,了解类之间的父子关系会很有帮助。 .NET Framework 大量使用继承,这意味着控件或类的许多属性和方法派生自层次结构中更高的另一个类。
下面是 WPF 中最常见类的子集的类层次结构视图。 (点击图片查看全尺寸)。
28 – DispatcherObject
DispatcherObject 类表示与 Dispatcher 关联的对象。调度程序处理在特定线程上工作的请求队列。它能够在其关联的线程上调用方法。
DispatcherObject 是对象的基类,这些对象跟踪与创建它们的线程关联的 Dispatcher。
WPF 控件从 DispatcherObject 继承,因为它们需要从创建它们的线程调用它们的方法。
DispatcherObject 有两个方法可以帮助确保从正确的线程调用控件的方法。
- CheckAccess – 检查当前线程是否可以调用控件上的方法
- VerifyAccess – 如果没有访问权限,则抛出InvalidOperationException
如果控件确定当前线程没有访问权限,它可以使用其 Dispatcher 属性(也在 DispatcherObject 中)在正确的线程上调用方法。
29 – 依赖属性
DependencyObject 是支持依赖属性的类的基类。
WPF 中的依赖属性类似于标准的 CLR 属性,但功能更强大。依赖属性:
- 从多个不同来源之一获取它们的值
- 支持属性值的继承
- 支持通知,当属性值更改时
如果类派生自DependencyObject,则该类可以注册自己的依赖属性并调用方法来获取/设置其依赖属性的值。
30 – Visual 类
Visual 是表示可呈现到 WPF 窗口或页面的对象的所有类的基类。它支持命中测试、裁剪和坐标变换,以及将自身呈现到窗口或页面。它还通过其 VisualParent 属性和 GetVisualChild 方法对对象在 WPF 可视化树中的参与进行建模。
Visual 类还可以用作实现新(轻量级)WPF 控件的起点。