目录
WPF体系结构
整个体系分为3层:
- 托管WPF层
- PresentationFramework.dll:包含了WPF顶层的类型,包括那些表示窗口、面板以及其他类型控件的类型。它还实现了高层编程抽象,如样式。
- PresentationCore.dll:包含了基础类型,如UIElement和Visual类,所有形状类和控件类都继承自这两个类。
- WindowBase.dll:包含了更多基本要素,如DispatcherObject类和DependencyObject类,这两个类引入了依赖属性。
- 媒体集成层
- milcore.dll:是WPF渲染系统的核心,实现WPF和DirectX的通信。
- WindowsCodecs.dll:提供图像支持的低级API,如处理、显示以及缩放位图和JPEG图像。
- 系统层
- Direct3D:一套低级API,WPF应用程序中的所有图形都由它进行渲染。
- User32:用于解决哪些应用程序实际占有桌面的哪一部分,在WPF中,它不负责渲染通用组件。
类层次结构
-
System.Threading.DispatcherObject
类
提供对WPF线程(STA单线程亲和)模型的支持; -
System.Windows.DependencyObject
类
提供WPF特有的依赖属性特性; -
System.Windows.Media.Visual
类
提供绘图的支持; -
System.Windows.UIElement
类
提供对WPF本质特征的支持,如布局、输入、焦点和事件。还添加了对数据绑定、动画以及样式等核心特性的支持; -
System.Windows.FrameworkElement
类
作为UIElement的唯一派生类,提供了更多跟尺寸布局相关的支持,以及Trigger(触发器); -
System. Windows.Shapes.Shape
类
提供了WPF对形状类的支持; -
System.Windows.Controls.Control
类
提供了对控件的外观和行为的支持,最重要的功能就是模板化。 -
System. Windows. Controls. ContentControl
类
是所有具有单一内容控件的基类,如Border
,Window
。 -
System. Windows.Controls. ltemsControl
类
是所有显示选项集合控件的基类,如ListBox
,TreeView
。 -
System.Windows.Controls.Panel
类
是所有布局容器类的基类,如StackPanel
,WrapPanel
。
什么是Template以及它有哪些分类?
Template(模板)用于定义或重定义控件结构
- ControlTemplate
- ItemsPanelTemplate
- DataTemplate
什么是Style?
样式是应用于元素的属性值的集合,是属于资源中重要的一种。样式支持触发器Trigger,支持设置依赖属性,支持关联事件处理,支持继承。
什么是Trigger以及它有哪些分类?
Trigger(触发器)是指当指定的属性、数据或事件发生变化或触发时执行的操作,一般用来调整样式,显示动画等。
- Trigger: 简单触发器,检测依赖项属性的变化,就会启动触发器,使用设置器改变样式
- MultiTrigger: 多重触发器,只有满足了所有条件,才会启动触发器。
- DataTrigger:数据触发器,与Trigger类似,只是它监视的是绑定数据的变化
- MultiDataTrigger:多重数据触发器,满足所有监视的数据条件,才会启动触发器
- EventTrigger: 事件触发器,当一个事件发生时,启动触发器,一般用于动画。
Binding(数据绑定)的用法
- Source(绑定源),没有指定source时使用DataContext作为数据源
- Path(路径),没有指定path或
path=.
时,表示直接以Source本身作为绑定的数据 - Convert转换器
- Mode数据流向,取值为
TwoWay
,OneWay
,OneTime
,OneWayToSource
,Default
- UpdateSourceTrigger更新时机,取值为
PropertyChanged
,LostFous
,Explicit
,Default
路由事件的三种方式
路由事件
- 直接路由事件:只在触发元素,不传递给其他元素。
- 冒泡路由事件:从触发的元素,向上传递。
- 隧道路由事件:从根元素触发,然后向下传递,直到触发事件的元素。
资源的分类以及它们的区别?
-
StaticResource
:静态资源,不会响应资源的变化。 -
DynamicResource
:动态资源,会响应资源的变化。
XAML和BAML的区别
BAML是一种压缩声明行语言,加载和解析速度比XAML快。
动画
- 简单线性动画
由变化起点、变化终点、变化幅度、变化时间4个要素构成:- 变化起点(
From
):如果没有指定变化起点则以变化目标属性的当前值为起点。 - 变化终点(
To
):如果没有指定变化终点,程序将采用上一次动画的终点或默认值。 - 变化幅度(
By
):如果同时指定了变化终点,变化幅度将被忽略。 - 变化时间(
Duration
):必须指定,类型为Duration
- 变化起点(
- 关键帧动画
由几个关键帧对象(**KeyFrame)组合成的关键帧集合(**AnimationUsingKeyFrames)来设定的动画叫关键帧动画。
对整个动画进行描述,通过Storyboard.TargetName
、Storyboard.TargetProperty
以及Duration
设置动画的目标和变化时间。
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MyAnimatedTranslateTransform"
Storyboard.TargetProperty="X"
Duration="0:0:10">
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:0" />
<LinearDoubleKeyFrame Value="350" KeyTime="0:0:2" />
<LinearDoubleKeyFrame Value="50" KeyTime="0:0:7" />
<LinearDoubleKeyFrame Value="200" KeyTime="0:0:8" />
</DoubleAnimationUsingKeyFrames>
- 路径动画
沿着指定路径移动的动画。
使用路径动画类(类型名+AnimationUsingPath
),并由路径对象(PathGeometry
)指定路径的动画。
参考资料
逻辑树和视觉树
- 逻辑树是由添加的元素的分类和层次组成的,不管这个添加的元素是通过XAML还是代码编写,所有WPF的特性(属性,事件,资源等)都是依赖于逻辑树的。
- 视觉树是逻辑树的扩展,逻辑树的每个节点都被分成为它们的核心视觉组件,只有从
System.Windows.Media.Visual
和System.Windows.Media.Visual3D
继承的元素才能被视觉树包含。 - 逻辑树可以通过
System.Windows.LogicalTreeHelper
来遍历,视觉树可以通过System.Windows.Media.VisualTreeHelper
来遍历; - 逻辑树可以在构造函数中遍历,视觉树需要经过至少一次布局后才能才行,所以通常是在
OnContentRendered
中进行。
多线程
有如下几种方式:
Thread
ThreadPool
Task
BackgroundWorker
注意:Thread
的IsBackground
默认为false
,也就是该线程对调用它的线程不产生依赖,当调用线程退出时该线程也不会结束。ThreadPool
和Task
的IsBackground
默认为true
,来指明该线程是后台线程,当主线程退出时该线程也会结束。BackgroundWorker
支持进度事件和取消消息
多线程更新UI
- Dispatch
- TaskScheduler
参考资料
WPF性能优化
- 尽量精简UI结构
- 对
ItemsControl
使用虚拟化 - 尽量绑定
IList
而不是IEnumerable
到ItemsControl
- 尽量使用
StaticResource
,而不是DynamicResource
- 改变
Brush
(画刷)的透明度而不是element
(元素)的 - 避免在
Text
属性上使用Run
- 使用合适的图像尺寸,并尽可能小
- 在单独的线程上处理耗时操作,比如加载数据
WPF中如何使用Winform控件
- 引用
WindowsFormsIntegration.dll
和System.Windows.Forms.dll
- 引入命名空间
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
- 使用
wfi:WindowsFormsHost
作为Winform控件的容器。