0

0

WPF 使用 Composition API 做高性能渲染

絕刀狂花

絕刀狂花

发布时间:2025-09-13 08:54:17

|

363人浏览过

|

来源于php中文网

原创

在 wpf 中,许多开发者会遇到渲染性能的问题。尽管 wpf 的渲染性能比浏览器渲染要高出不少,但仍然无法满足游戏级别的渲染需求。wpf 使用的 directx 版本仅优化到 9 级别,与 directx 9 的性能相当。鉴于开发者的需求,微软推出了现代渲染方法——composition api,这是一个 ui 应用的里程碑技术。

目前,这个技术还处于最小可用版本阶段,但已经可以尝试使用。

首先,需要将系统更新到 1803 或更高版本。如果您想成为 Windows 开发者,则需要确保系统是最新的。

接着,下载并安装 Visual Studio 2019 的最新版本,并安装 .NET Core 3.0 的预览版。

官方下载链接:Visual Studio 2019.NET Core

下载运行代码,可以从 GitHub 官方仓库 https://www.php.cn/link/508cb643c0ea0e2f6451bba7aa5cfb64 获取最新代码,并尝试编译运行。

打开

dotnet\WPF\HelloComposition
目录中的解决方案,确保使用 Visual Studio 2019 打开。

通过 NuGet 还原两个库:Microsoft.Windows.SDK.Contracts,这是一个包含桌面使用的 Windows Runtime API 的库,以及 System.Numerics.Vectors,用于支持向量计算。

HelloComposition 是一个最简单的项目,可以通过这个项目了解使用方法。

由于这个项目目前仍处于预览阶段,建议使用命令行进行编译。我在开始时发现这个项目使用的是旧版的 csproj 格式,并且无法直接在 Visual Studio 2019 中编译成功。因此,我将项目格式更新为新格式,通过命令行还原并编译后,就可以在 Visual Studio 2019 中进行调试。

修改方法是用以下代码替换 HelloComposition.csproj 文件,并删除

HelloComposition\Properties\AssemblyInfo.cs
文件:


  
    WinExe
    netcoreapp3.0
    true
  
  
    
      10.0.17763.144-preview
    
    
      4.5.0
    
  

如果不想自己修改 csproj 文件,可以下载我修改后的版本,并通过命令行进行还原和编译:

# 进入 HelloComposition.sln 所在的文件夹
dotnet restore # 如果还原失败,可以参考我收集的各种公有 NuGet 源:https://walterlv.com/post/public-nuget-sources.html
dotnet build

如果编译成功,就可以在 Visual Studio 2019 中点击运行调试。如果编译失败,欢迎加入 .NET 职业技术学院交流群。

运行后可以看到以下图片:

WPF 使用 Composition API 做高性能渲染

项目主要代码是如何编写的呢?

主要代码集中在 CompositionHostControl 这个普通的 UserControl 控件中。在控件加载时,将其内容,即一个名为 CompositionHostElement 的 Border 的内容,修改为 CompositionHost 的方法。

白果AI论文
白果AI论文

论文AI生成学术工具,真实文献,免费不限次生成论文大纲 10 秒生成逻辑框架,10 分钟产出初稿,智能适配 80+学科。支持嵌入图表公式与合规文献引用

下载

CompositionHost 是一个自定义的 HwndHost 方法,通过 HwndHost 可以指定为 Host 一个句柄,从而让 WPF 使用两种不同的渲染方法。

在 CompositionHost 中创建了一个新窗口,并使用 HwndHost 将其显示在 WPF 窗口之上。因此,使用 CompositionHost 的控件将显示在其他任何 WPF 控件的上面,在 CompositionHost 控件的 Bounds 范围内,不能使用其他 WPF 控件。这与在 WPF 中使用其他渲染方法的窗口类似,也是在 WPF 中使用 WinForms 或 UWP 控件的技术。

CompositionHost 的主要代码是 InitComposition 方法,在这里通过黑科技方法创建了 Composition。由于我不了解这些黑科技,所以就跳过了。

跳过这个类后,其余代码非常简单,可以看到方法接口与 UWP 类似。在

CompositionHostControl_Loaded
方法中返回了 Compositor 字段,其使用方式与 UWP 相同。

private void CompositionHostControl_Loaded(object sender, RoutedEventArgs e)
{
    // 如果用户更改了屏幕的 DPI 缩放设置,CompositionHostControl 将重新加载。
    // 如果已经设置过,则不重复设置。
    if (compositionHost is null)
    {
        currentDpi = VisualTreeHelper.GetDpi(this);
        compositionHost = new CompositionHost(CompositionHostElement.ActualHeight, CompositionHostElement.ActualWidth);
        // 手动高亮,下面的代码将 CompositionHostElement 这个 Border 的内容修改为 CompositionHost 这个 HwndHost,通过 Host 一个窗口的方法
        CompositionHostElement.Child = compositionHost;
        // 手动高亮,下面的代码返回 Compositor 字段
        compositor = compositionHost.Compositor;
        // 手动高亮,下面的代码返回 ContainerVisual 字段
        containerVisual = compositor.CreateContainerVisual();
        compositionHost.Child = containerVisual;
    }
}

在点击按钮时,创建一个 SpriteVisual 并加入到 ContainerVisual 中,然后进行 Vector3KeyFrameAnimation 动画。

这里的代码接口与 UWP 相同,因此不再详细介绍如何使用。

通过 HwndHost 方法获取一个窗口的句柄并不是直接在 WPF 中使用 Composition,而是在创建一个窗口时使用 Composition,因为 WPF 的渲染与 Composition 的渲染不同。

由于使用了这种技术,会存在一些问题,下面将详细介绍。

通过 COM 等方法调用额外的系统相关接口,如果只是创建一个空白窗口,是无法直接使用 Composition API 的,需要使用一些黑科技,这些代码都在

CompositionHost
中。由于我也看不懂,所以就跳过了。

如果想了解更多,请参考 Using the Visual Layer with WPF。

将 Visual Layer 的内容封装在 WPF 的用户控件中,CompositionHostControl 这个用户控件使用了封装的 Visual Layer,其内部代码与 UWP 相同。

如何使用可以参考 UWP 的 Visual Layer 文档。

预览代码中主要用到的类有三个:

  • CompositionHost:连接 WPF 的渲染和 UWP 的 Visual Layer,也是这个项目的主要代码。官方建议直接复制这个类中的代码,参考 Create an HwndHost derived class to host composition elements。
  • CompositionHostControl:使用封装后的方法,简单介绍如何添加 Visual 和动画。
  • 主窗口:里面放了一个按钮和 CompositionHostControl,代码非常简单。

尽管可以在 WPF 中使用 Composition API 制作出美观的界面,但由于主要技术是通过 HwndHost 方法,这种方法尚未正式使用,因此存在以下不足:

  • 特效依赖于 Win2d,但目前 Win2d 尚未支持桌面的 NuGet 库,需要编译源代码。不过很快就可以通过 NuGet 直接使用。
  • 如果需要交互命中测试,需要在代码中计算 Visual Layer 的 Bounds。与在 UWP 中通过 XAML 的方法简单绑定对应的命中测试相比,这并不简单。不过很快就会有封装的方法。
  • 目前的 Visual Layer 尚未支持渲染文本,但可以通过 SharpDX 的方法渲染,很快就可以原生支持。
  • 由于使用的是 Host 技术,不能在 DPI 修改时自动缩放,需要编写大量代码进行适配。

如果上述几个问题都可以解决,那么下面的问题就是原理上的问题。由于使用了 HwndHost 方法,使用了两种渲染方法,在使用 UWP 渲染方法的范围内,窗口的最上层将无法放置任何 WPF 的像素,同时也存在焦点等问题。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1025

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

66

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

452

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

10

2026.01.19

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

465

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

13

2025.12.06

html边框设置教程
html边框设置教程

本教程将带你全面掌握HTML/CSS边框设置,从基础的border属性讲起,涵盖所有边框样式、圆角设置及高级技巧,帮助你快速上手实现各种边框效果。

32

2025.09.02

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

601

2023.07.26

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

6

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

AngularJS教程
AngularJS教程

共24课时 | 2.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号