WPF 使用 MAUI 的自绘制逻辑

这是一个当前还没开发完成的功能,准确来说连预览版也算不上的功能。我原本以为 MAUI 是无法在 WPF 上面跑的,然而在看完了 MAUI 整个大的设计,才了解到,原来 MAUI 是一个非常庞大的开发项目。在 MAUI 里面,虽然现在是正式发布的,但正式发布的版本里面只有采用原生控件进行绘制的方案。这和官方开始的宣传不符合,在阅读了 MAUI 相关文档才发现,实际上 MAUI 还有一个很大的部分,那就是自绘部分,还没完成,代码也分了仓库,这就是一开始没找到的原因。本文将告诉大家 MAUI 还没发布的这部分大杀器

本文所涉及的全部都是绘制的渲染层,而众所周知,一个 UI 框架最重要的两个部分就是交互和渲染。本文仅仅只会涉及到渲染的一部分

cfc23c0344cabf34f349064f3a5eab74.png

制作一个跨平台的 UI 框架有很多个方式,例如使用各个平台提供的原生控件,也就是说在 Windows 平台上,采用 WinUI 的按钮,在 iOS 平台上使用苹果提供的按钮,具体的按钮样式等等就需要取平台最小集以及开放定制性,最重要的代表就是原先的 Xamarin 的方式。采用各个平台的提供的原生控件的一个优势在于可以获取平台提供的功能,更加贴合具体平台的视觉和交互,缺点是不同的平台的视觉效果有所差异。另一个方式是做中间较底层的自绘,基本上各个平台都会提供自绘的能力,如 WPF 下的 DrawingContext 和 Win2D 等等,基于此方式做自绘,可以更加方便接入原有的平台,降低原有的应用接入的成本,而这就是本文的重点。最后一个方式是做底层的自绘,使用平台最底层的绘制逻辑,或者其他渲染框架的封装进行二次封装,如 Skia 或 GTK 等,对此进行渲染。使用底层的自绘逻辑可以做到更多的可控性,但缺点也在于可控性导致开发起来十分麻烦,与现有的应用接入也相对来说无法实现最好的性能

3ab7c22e74b20c3ea56d3b7175499ede.png

很多的 UI 框架都会采用其中的一个方式。然而别忘了 MAUI 是某软主力做的,按照某软的想法,那就是都要。在 MAUI 里面,既可以使用平台提供的原生控件进行拼接制作界面,也可以使用基于的各个平台的独立 UI 框架提供的自绘能力绘制界面,也可以调用到底层的渲染逻辑进行渲染

但,这也不是免费的。如此大的一个项目,自然投入的成本,无论是人力还是开发周期,都是非常庞大的。尽管现在 MAUI 正式发布了,可惜还有很大部分的工作还没完成,甚至还没开始

在吸取了很多次失败的教训之后,某软决定拆分仓库,以解决如此大的一个项目的某些组件或部分的失败带来整体的失败。这是 dotnet runtime 组的成功的例子带来的组织形式的经验,在 dotnet runtime 里面,将不稳定的实验的功能放在 .NET Runtime Lab 仓库里面。不稳定的功能,如果能成,那自然能大大提升 dotnet 的竞争力,如果不成也不应该影响到整个 dotnet 的发布

当前的 MAUI 也是这个管理方式,在 MAUI 里面,将渲染层拆出一个 Microsoft.Maui.Graphics 仓库,如 MAUI 自定义绘图入门 所提到的。其实 Microsoft.Maui.Graphics 是由原本的 System.Graphics 改名而来。这个 System.Graphics 项目初步完成时间比 MAUI 早很多,定位是做全平台的绘制封装层,提供了各个平台的绘制渲染的上层统一。包括了两个实现方式,一个是对各个平台提供的 UI 框架的自绘逻辑进行封装,从而对上层统一。另一个方式对各个底层绘制渲染逻辑包括 Skia 和 GTK 甚至是 DirectX 进行封装,从而提供给上层统一的逻辑,只需要简单的代码即可切换

ed4fd9c5a2f085a9f61fd514e4a55435.png

接下来是在有 Microsoft.Maui.Graphics 的基础上,也就是在能提供各个平台上层统一的绘制能力之后,进行实现各个基础控件。这就是 Microsoft.Maui.Graphics.Controls 仓库,这个仓库的需求就是制作自绘的控件。如此即可实现各个平台上像素级的统一,或者是更加方便接入原有的应用的 UI 框架

本文是在 2022.06 写的,以上的很多功能都只是能吹不能用。但是只是写一篇水文,那可不是我的风格。自然就是开始实际的写代码阶段

认识我的伙伴们都知道,我对渲染是比较熟悉的。我接下来将告诉大家,如何使用 Maui 提供的框架层,配合 WPF 提供具体的自绘逻辑,两个放在一起,从而实现 WPF 使用 MAUI 的自绘逻辑

08216f0b070742771cb62eac48d5c9f0.png

核心的实现方法是 WPF 提供画布功能,让 MAUI 可以在 WPF 上面画元素。在 MAUI 里面提供框架,以及具体的绘制指导,和上层 API 调用

本文以下部分将用到还没有发布,但是也差不多快完成的 Microsoft.Maui.Graphics.Xaml.WPF 提供的功能。这个库的代码放在 Microsoft.Maui.Graphics 仓库,这个库属于做中间较底层的自绘,利用 WPF 提供的丰富的绘图能力从而介入 MAUI 定义的抽象接口。由于此库还没完成,为了完成接入,我没有使用 DLL 引用,而是拷贝了这个库的代码到我的测试代码里面,然后再进行稍微的魔改,解决构建不通过

大概的对接方式如下,先在 WPF 里面放一个 Canvas 控件,这个控件将被作为 MAUI 的画布。如此也能解答一些伙伴的疑惑,那就是 MAUI 接入 WPF 的话,能作为控件的形式接入,而不作为类似 WindowsFormsHost 的方式接入。如本文下面的代码,只是提供一个 Canvas 控件,让 MAUI 将内容绘制在这个 Canvas 上。如此可见 MAUI 的大的方面的设计还是很好

<Canvas x:Name="Canvas" />

在后台代码里面,将创建 XamlCanvas 类型的 _canvas 字段,同时将上面代码的 Canvas 传入

public partial class MainWindow : Window{    public MainWindow(){InitializeComponent();_canvas.Canvas = Canvas;SizeChanged += (source, args) => Draw();}    public IDrawable Drawable{        get => _drawable;        set{_drawable = value;Draw();}}    private void Draw(){        if (_drawable != null){            using (_canvas.CreateSession()){_drawable.Draw(_canvas, new RectF(0, 0, (float) Canvas.Width, (float) Canvas.Height));}}}    private readonly XamlCanvas _canvas = new XamlCanvas();    private IDrawable _drawable;
}

以上代码的 XamlCanvas 继承了 ICanvas 接口。在 MAUI 的自绘里面,最重要的就是 ICanvas 接口,这是一个表示画布的接口,在这个接口里面实现了具体的绘制的抽象 API 定义。换句话说,如果你想要接入自己想要的其他平台,那很重要的一点就是去实现 ICanvas 的功能

以上的 XamlCanvas 是属于库提供的功能,将通过传入的 Canvas 实现对接 MAUI 和 WPF 的逻辑

有了画布之后,想要在界面绘制内容,那还需要告诉框架层想要画出什么内容。这就是属于业务层的内容了,在业务层里面,将需要继承 IDrawable 接口,实现 Draw 方法。在 Draw 方法进行业务层的渲染

例如一个画线的业务功能,可以使用如下实现方式

class DrawLines : IDrawable{        public void Draw(ICanvas canvas, RectF dirtyRect){canvas.DrawLine(50, 20.5f, 200, 20.5f);canvas.DrawLine(50, 30.5f, 200, 30.5f);}}

将 DrawLines 的对象设置给 Drawable 属性,即可看到界面画出线

以上的 DrawLines 就是属于 通用 MAUI 渲染层 的逻辑,将这段代码拿出来,可以跑在使用其他底层渲染技术但是接入 Microsoft.Maui.Graphics 的渲染技术,例如底层换成是 Win2D 等。如此即可通过造上层的 通用 MAUI 渲染层的逻辑,从而搭建起界面效果的生态。更多自定义的绘图,请看 MAUI 自定义绘图入门 - lindexi - 博客园

我十分推荐大家跑一下我的 demo 从而了解到当前的 MAUI 的实现进度

本文测试代码放在github 和 gitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git initgit remote add origin https://gitee.com/lindexi/lindexi_gd.gitgit pull origin 8d4c37dbbde83e03a6daa4e3454a5d007c64dffe

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git

获取代码之后,进入 RijoqicainejoHifolurqall 文件夹

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285639.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[转]redis 5.0.5 5分钟搭建redis集群

环境&#xff1a;centos 7 1&#xff1a;下载并安装redis ​​​​​​​$ wget http://download.redis.io/releases/redis-5.0.5.tar.gz$ tar xzf redis-5.0.5.tar.gz$ cd redis-5.0.5$ make redis 5.0版本 集群搭建不需要我们安装ruby就可以搭建成功&#xff0c;并且redis…

Window.document对象

一、找到元素&#xff1a; docunment.getElementById("id")&#xff1b;根据id找&#xff0c;最多找一个&#xff1b; var a docunment.getElementById("id");将找到的元素放在变量中&#xff1b; docunment.getElementsByName("name")&am…

C# 读写文件从用户态切到内核态,到底是个什么流程?

一&#xff1a;背景 1. 一个很好奇的问题我们在学习 C# 的过程中&#xff0c;总会听到一个词叫做 内核态 &#xff0c;比如说用 C# 读写文件&#xff0c;会涉及到代码从 用户态 到 内核态 的切换&#xff0c;用 HttpClient 获取远端的数据&#xff0c;也会涉及到 用户态 到 内核…

【土地评价与土地管理】案例:某地区土地农业利用潜力评价

文章目录 一、确定评价单元二、拟定潜力评价系统表、确定指标权重三、指标评价四、评定潜力等级五、得出潜力评价结果一、确定评价单元 土地潜力评价单元采用地块作为评价单元,此地块是建立在土地利用现状的基础上, 综合土地的自然属性来确定,评价单元界线与土地现有界线基本…

code point,code unit

2019独角兽企业重金招聘Python工程师标准>>> 从一段API描述谈起&#xff1a; 在String的length的API中描述是这样的&#xff01; lengthpublic int length() Returns the length of this string. The length is equal to the number of 16-bit Unicode characters i…

【土地评价与土地管理】案例:兰州市榆中县农用地分等

文章目录 一、资料收集二、确定标准耕作制度、基准作物、指定作物、光温(气候生产潜力)三、划分指标区,确定分等因素及权重四、编制“指定作物-分等因素-自然质量分”记分规则表五、绘制分等因素分值图,划分分等单元六、计算农用地自然质量分七、计算自然质量等指数八、计算…

业务多变的公司上云后蒸蒸日上

一、云服务器与传统服务器的对比 1&#xff09;、传统服务器 传统服务器是一个独立的硬件设备,可以理解成是一台放在机房的高配置电脑,可根据需求安装各种操作系统以及配置各种环境,性能也比较强大。 2&#xff09;、云服务器 云服务器是构建在硬件服务器集群之上&#xff0c;…

2016福州大学软件工程第四次团队作业-系统设计成绩汇总

第四次团队作业——系统设计打分统计结果如下&#xff1a; 学号组别团队分数贡献比例个人分数031401433606notconnected141613.83031402606606notconnected141413.33031402618606notconnected141814.34031402629606notconnected141413.33031402631606notconnected141914.590314…

[转]在C#中像Python一样编写TensorFlow机器学习代码

机器学习是一个令人激动人心的领域&#xff0c;一直有新的技术突破。研究人员不断推动机器智能的提升&#xff0c;教机器如何听说读写——这些曾经是我们人类专属的技能。机器学习的首选语言是Python&#xff0c;最受欢迎的库是Google的TensorFlow。几乎所有的代码示例都是用Py…

【土地评价与土地管理】教案 第一章:土地评价要素的选择

文章目录 1.1 土地构成要素与其农业利用1、光能条件2、热量条件3、降水条件1.1 土地构成要素与其农业利用 1、光能条件  光能是绿色植物进行光合作用和生物运动发展的主要能源  太阳辐射、日照时数  太阳辐射量随地域和季节变化较大,导致了土地利用的多样性和土地资源…

Blazor University (33)表单 —— EditContext、FieldIdentifiers

原文链接&#xff1a;https://blazor-university.com/forms/editcontext-fieldidentifiers-and-fieldstate/EditContext、FieldIdentifiers 和 FieldState请注意&#xff0c;对于那些希望了解 Blazor 如何“在后台”工作的人来说&#xff0c;这是一个高级主题。无需了解此信息即…

团队项目开发篇章8

例会时间&#xff1a;2016.11.3 整理&#xff1a;姬索肇 例会照片 每个人的工作 任务分配 我们今天与王鹿鸣学长和李云涛学长针对团队开发过程中遇到的问题进行了讨论&#xff0c;非常感谢学长们的热心帮助&#xff0c;同时我们也被他们强大的编程能力所折服~ 在这里为学长们点…

【地理信息系统GIS】教案(七章全)第一章:地理信息系统概述

文章目录 第一节 GIS基本概念第二节 GIS的组成第三节 GIS的功能第四节 GIS的发展第一节 GIS基本概念 1.1 GIS基本概念 1、信息 是用文字、数字、符号、语言、图象、图形等介质来表达事件、事物或现象等的内容、数量和特征,从而向人们(或系统)提供关于现实世界新的事实和知…

表达式的动态解析和计算,Flee用起来真香

前言在很多项目中经常会出现需要动态解析表达式和计算的场景&#xff0c;比如一些自动审核规则&#xff0c;或者是一些变量的值通过维护的公式在运行过程中动态算出&#xff1b;由于场景需求&#xff0c;都需要比较灵活的配置对应的表达式&#xff0c;然后希望在需要的时候能根…

C语言九十五之实现经典的反转数组(通过指针或数组下标操作)

✅作者简介&#xff1a;大家好我是码玛莎拉蒂&#xff0c;CSDN博客专家&#x1f947;&#x1f947;&#x1f947; &#x1f4c3;个人主页&#xff1a;个人主页 &#x1f525;系列专栏&#xff1a;C语言试题200例 &#x1f4ac;推荐一款模拟面试、刷题神器&#x1f449; 点击跳转…

Linux下使用shell实现上传linux下某个目录下所有文件到ftp

首先我们需要搞清楚单个文件怎么上传&#xff0c;把这个单文件上传到ftp上的实现命名为一个:upload_to_ftp_command.sh 之后&#xff0c;需要弄清楚怎么实现遍历一个目录下的所有文件的&#xff0c;把这个遍历某个目录下的文件实现命名为&#xff1a;foeach_directory_and_uplo…

[转]Mysql数据库开发的36条原则

前言 这些原则都是经历过实战总结而成 每一条原则背后都是血淋淋的教训 这些原则主要是针对数据库开发人员&#xff0c;在开发过程中务必注意 总是在灾难发生后&#xff0c;才想起容灾的重要性&#xff1b; 总是在吃过亏以后&#xff0c;才记得曾有人提醒过。 一、核心原则…

大话领域驱动设计——表示层及其他

概述表示层又称用户界面层&#xff0c;包含应用程序的页面、组件等UI元素。服务层提供项目的HTTP API接口&#xff0c;包含MVC Controller和相关组件。ABP框架虽然在表示层提供了不少组件&#xff0c;但是这些和DDD本身没有多少关系。而且随着前后端分离架构的流行&#xff0c;…

Windows10家庭中文版没有本地策略选项完美解决方案

Win+R,在运行中输入:secpol.msc,查看安全设置是否打开,如下图所示。 组策略对于优化和维护Windows系统来说十分重要。众所周知,Windows 10家庭版中并不包含组策略,对于使用家庭版Windows的朋友来说,十分不方便。 通常情况下,如果策略组没有打开的话,在安装CAD等软件时…

【ArcGIS风暴】栅格计算器(Raster Calculator)运算出现错误问题及解决方案汇总

栅格计算器(Raster Calculator) 是一种空间分析函数工具,可以输入地图代数表达式,使用运算符和函数来做数学计算,建立选择查询,或键入地图代数语法。只有熟练的运用并记忆一些常用的公式,才能很好的运用栅格计算器。在使用的过程中,容易出现这样那样的问题,本文就把栅…