底层
Visual对象将作为其呈现数据存储向量图形指令列表。 指令列表中的每一项都以序列化格式表示一组低级别的图形数据及其相关资源。 共有四种不同类型的呈现数据可以包含绘图内容。
DrawingContext可以来填充Visual可视化内容。 当你使用DrawingContext对象的绘图命令时,实际上存储一组图形系统将更高版本使用的呈现数据; 你不绘制到实时屏幕。
WPF 引入了多个影响可视化对象呈现行为的功能:保留的模式图形、矢量图形和与设备无关的图形。
视觉对象的呈现行为 WPF 引入了多个影响可视化对象呈现行为的功能:保留的模式图形、矢量图形和与设备无关的图形。
保留的模式图形
了解 Visual 对象角色的关键之一是,了解即时模式和保留模式图形系统之间的区别。
基于 GDI 或 GDI+ 的标准 Win32 应用程序使用即时模式图形系统。 这意味着应用程序负责重新绘制由于某项操作(如重设窗口大小)或者对象的可视化外观发生变化而失效的工作区部分。
相比之下,WPF 使用保留模式系统。 这意味着具有可视化外观的应用程序对象定义一组序列化绘图数据。 在定义了绘图数据之后,系统会响应所有的重新绘制请求来呈现应用程序对象。 甚至在运行时,用户可以修改或创建应用程序对象,并仍依赖于系统响应绘制请求。 保留模式图形系统中有一个强大功能,即绘图信息总是由应用程序保持为序列化状态,但是呈现功能仍由系统负责。
使用保留模型图形的最大好处之一就是,WPF 可以高效率地优化需要在应用程序中重绘的内容。 即使存在一个具有各种不透明度的复杂场景,通常也不必编写特殊用途的代码来优化重绘功能。 将该功能与 Win32 编程进行比较,在后者中可以通过最小化更新区域中的重绘量来尽力优化应用程序。 有关在 Win32 应用程序中优化重绘功能时涉及到的复杂度类型的示例,请参阅在更新区域中重绘。
矢量图形,关于与分辨率和设备无关的图形
基本 Ellipse、Rectangle、Line 延伸 Polygon、 Polyline 和 Path 元素支持基础矢量图
矢量图,当然放大后,不会变形
WPF 源代码 从零开始写一个 UI 框架 | WPF 源代码 从零开始写一个 UI 框架 | |
WPF线程处理模型 | 线程处理模型 - WPF .NET Framework | Microsoft Learn | |
WPF 图形呈现疑难解答 | 图形呈现概述 - WPF .NET Framework | Microsoft Learn | |
WPF 渲染原理 | WPF 渲染原理 | |
深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分) | https://blog.walterlv.coWPF 渲染原理m/post/dotnet/2017/09/26/dispatcher-invoke-async.html | |
深入了解 WPF Dispatcher 的工作原理(PushFrame 部分) | 深入了解 WPF Dispatcher 的工作原理(PushFrame 部分) - walterlv | |
路由事件概述 | 路由事件概述 - WPF .NET Framework | Microsoft Learn | |
什么是模态窗口?本文带你了解模态窗口的本质 | 什么是模态窗口?本文带你了解模态窗口的本质 - walterlv | |
WPF 全球化和本地化概述 | 全球化和本地化概述 - WPF .NET Framework | Microsoft Learn | |
WPF国际化/多语言支持 | WPF国际化/多语言支持-昨夜星辰 |
UI虚拟化 | 物理滚动 逻辑滚动 | CanContentScroll=True | ||
Binding | TemplateBinding 只能单向 | |||
在Template中 OnewayToSource,TwoWay | RenderingSize="{Binding AreaSize,RelativeSource={RelativeSource TemplatedParent},Mode=OneWayToSource}" | |||
Waves="{Binding RealTimeECGModel.Waves}" 这种子属性Binding会有问题 | ||||
生命周期 | Window.GetWindow 必须得在Load之后 | 因为只有Load之后,视觉树才会完成 | ||
Image | Image虽然是FE,但是没有填充之前,是没有大小的,可是没有大小,画布也不会画,所以不能直接用Image做基类 | |||
ViewModel | ViewModel 必须在View 构造函数中创建,否则,注册消息,Load事件等,就都没了 | |||
Dialog | 解决关闭模态窗口后,父窗口居然失去焦点跑到了其他窗口的后面的问题 | Closing += (sender, e) => Owner?.Activate(); | 解决关闭模态窗口后,父窗口居然失去焦点跑到了其他窗口的后面的问题 - walterlv | |
源码 | DispatcherTimer 本质就是 Dispatcher.Begininvoke 加上 时间轮 | |||
透明 | 不要使用AllowsTransparency | WPF 从最底层源代码了解 AllowsTransparency 性能差的原因 | ||
窗体 | ResizeMode="NoResize" 不可拖拽大小,边框 | |||
背景 | 1WindowStyle="None" 去除windows 标题栏 2WindowChrome GlassFrameThickness=-1 用边框做背景色 3Template 更换模板 | 1 2 纯白 1 3 纯黑 2 3 系统标题栏主题色 123 透明 | ||
不要用 BitmapEffect,使用Effects
尽量不要使用dy,使用StaticResource Freeze Freezable
Hit Testing CachingHint
Binding | TemplateBinding 只能单向 | |||
在Template中 OnewayToSource,TwoWay | RenderingSize="{Binding AreaSize,RelativeSource={RelativeSource TemplatedParent},Mode=OneWayToSource}" | |||
Waves="{Binding RealTimeECGModel.Waves}" 这种子属性Binding会有问题 | ||||
生命周期 | Window.GetWindow 必须得在Load之后 | 因为只有Load之后,视觉树才会完成 | ||
Image | Image虽然是FE,但是没有填充之前,是没有大小的,可是没有大小,画布也不会画,所以不能直接用Image做基类 | |||
ViewModel | ViewModel 必须在View 构造函数中创建,否则,注册消息,Load事件等,就都没了 | |||
Dialog | 解决关闭模态窗口后,父窗口居然失去焦点跑到了其他窗口的后面的问题 | Closing += (sender, e) => Owner?.Activate(); | 解决关闭模态窗口后,父窗口居然失去焦点跑到了其他窗口的后面的问题 - walterlv | |
源码 | DispatcherTimer 本质就是 Dispatcher.Begininvoke 加上 时间轮 |
WPF 源代码 从零开始写一个 UI 框架 | WPF 源代码 从零开始写一个 UI 框架 | |
WPF线程处理模型 | 线程处理模型 - WPF .NET Framework | Microsoft Docs | |
WPF 渲染原理 | WPF 渲染原理 | |
深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分) | 深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分) - walterlv | |
深入了解 WPF Dispatcher 的工作原理(PushFrame 部分) | 深入了解 WPF Dispatcher 的工作原理(PushFrame 部分) - walterlv | |
路由事件概述 | 路由事件概述 - WPF .NET Framework | Microsoft Docs | |
什么是模态窗口?本文带你了解模态窗口的本质 | 什么是模态窗口?本文带你了解模态窗口的本质 - walterlv | |
WPF 从最底层源代码了解 AllowsTransparency 性能差的原因 | WPF 从最底层源代码了解 AllowsTransparency 性能差的原因 | |
WPF 全球化和本地化概述 | 全球化和本地化概述 - WPF .NET Framework | Microsoft Docs | |
WPF国际化/多语言支持 | WPF国际化/多语言支持-昨夜星辰 |