使用 Uno Islands 在现有 WPF 里面嵌入 Uno 框架
随着 2022 9 月份 Uno 发布了 4.5 版本,现有的 WPF 应用多了一个新的开发模式,那就是通过 Uno Islands 技术,在现有的 WPF 应用里面嵌入 Uno 应用。通过此方式可以辅助在现有的 WPF 项目里面,部分功能迁入 Uno 项目,或者是某些新开发功能通过 Uno 实现,从而利用 Uno 跨平台的能力,逐个功能点支持跨平台功能。逐个小功能接入的方式,让开发者不需要为一次性迁移一个庞大的项目而烦恼
本文将尝试写一个非常简单的例子用来尝试在一个空的 WPF 项目上,接入 Uno Islands 技术,核心代码完全来自 Uno 官方,详细请看 Uno Islands 官方文档
在开始之前,先介绍一下 Uno 项目是什么。这是一个支持用 C#+XAML 实现跨平台的 UI 框架,直接对标就是 MAUI 框架。只是 UNO 的主力开发不是微软官方,而是第三方开发者,而且还是特别特别卷的第三方开发者,总体开发进度预计是 MAUI 的 5-10 倍。在 MAUI 还没正式发布,还在进入预览版的时候,这时 UNO 早已发布商业可用版本。在 MAUI 还在打磨的时候,这时 UNO 开始不断发布各种新迭代功能了。说不定后续 UNO 还有被某软收购的可能
总的来说,我认为 UNO 还是比较能打的。而且更加有趣的是 UNO 和 MAUI 之间不是打架的关系,很多开发者都在这两个框架之间跑动。同样的 bug 要修两次,那才有趣
至于好不好用,我推荐大家试试看咯
回到主题,在今年 9 月份新加入的 Uno Islands 技术,让我开始准备在实际的大应用上部分功能接入 Uno 框架。通过 Uno Islands 技术,可以在 WPF 里面划某个矩形范围,让这个范围内的内容使用 Uno 框架进行绘制和交互。为了方便演示,接下来新建一个空白的 WPF 项目,在这个空白的 WPF 项目里面,在主窗口同时放一个 WPF 的控件和一个用来承载 Uno 框架的 UnoXamlHost 控件,以及新建一个共享项目,在共享项目里面存放 Uno 框架所需的代码和编写简单的 UI 界面
新建一个空白的 WPF 项目,采用 dotnet 6 框架,编辑 csproj 项目文件,加上必要的引用
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<PackageReference Include="Uno.WinUI.Skia.Wpf" Version="4.5.9" />
<PackageReference Include="Uno.WinUI.RemoteControl" Version="4.5.0-dev.453" Condition="'$(Configuration)'=='Debug'" />
<PackageReference Include="Uno.UI.Adapter.Microsoft.Extensions.Logging" Version="4.5.0-dev.453" />
<PackageReference Include="Uno.WinUI.XamlHost" Version="4.5.0-dev.453" />
<PackageReference Include="Uno.WinUI.XamlHost.Skia.Wpf" Version="4.5.0-dev.453" />
</ItemGroup>
接着新建一个叫 TestUnoIslands 的共享项目,这个共享项目里面的文件内容和代码,推荐是从我的测试代码里面抄袭: https://github.com/lindexi/lindexi_gd/tree/7ddbfed126c37ec07d5d0d94468f5d0551e122f9/TestUnoIslands/TestUnoIslands
从我的测试代码仓库里面拷贝代码文件的方式可以快速拷贝出一个使用 Uno 框架的项目,这些代码逻辑和官方的例子 代码接近相同。从官方代码仓库里面拷贝例子也不错: https://github.com/unoplatform/Uno.Samples/tree/master/UI/UnoIslandsSampleApp/UnoIslandsSampleApp.Shared
这里的共享项目可以认为是一个现有的使用 Uno 框架的项目,接下来就是在刚才创建的 WPF 项目里面,嵌入这个 Uno 项目的内容
在刚才新建的 WPF 项目里面,添加共享项目的引用,引用刚才创建的共享项目,接着为了解决 Uno 的字体问题,在 WPF 项目里面添加 uno-fluentui-assets.ttf 字体,这个字体文件可以从 github 这里下载: https://github.com/lindexi/lindexi_gd/blob/7ddbfed126c37ec07d5d0d94468f5d0551e122f9/TestUnoIslands/TestUnoIslands.Wpf/Assets/Fonts/uno-fluentui-assets.ttf
添加的 ttf 字体文件放入到 Assets\Fonts 文件夹内,同时编辑 WPF 项目的 csproj 文件,添加这个 ttf 文件的引用
<ItemGroup>
<Content Include="Assets\Fonts\uno-fluentui-assets.ttf" />
</ItemGroup>
再编辑 WPF 项目的 csproj 文件,设置对共享项目里的 XAML 文件的引用
<ItemGroup>
<UpToDateCheckInput Include="..\TestUnoIslands\**\*.xaml" />
</ItemGroup>
编辑完成之后的 csproj 项目文件的内容如下
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<PackageReference Include="Uno.WinUI.Skia.Wpf" Version="4.5.9" />
<PackageReference Include="Uno.WinUI.RemoteControl" Version="4.5.0-dev.453" Condition="'$(Configuration)'=='Debug'" />
<PackageReference Include="Uno.UI.Adapter.Microsoft.Extensions.Logging" Version="4.5.0-dev.453" />
<PackageReference Include="Uno.WinUI.XamlHost" Version="4.5.0-dev.453" />
<PackageReference Include="Uno.WinUI.XamlHost.Skia.Wpf" Version="4.5.0-dev.453" />
</ItemGroup>
<ItemGroup>
<UpToDateCheckInput Include="..\TestUnoIslands\**\*.xaml" />
</ItemGroup>
<ItemGroup>
<Content Include="Assets\Fonts\uno-fluentui-assets.ttf" />
</ItemGroup>
<Import Project="..\TestUnoIslands\TestUnoIslands.projitems" Label="Shared" />
</Project>
接下来打开 WPF 项目的主窗口用来添加对 Uno 项目的引用。开始之前,在 XAML 加上命名空间
xmlns:xamlHost="clr-namespace:Uno.UI.XamlHost.Skia.Wpf;assembly=Uno.UI.XamlHost.Skia.Wpf"
这是一句话的命名空间引用,官方的文档里面为了格式化,在文档里面换了行
通过添加 Uno Island 即可进行对 Uno 项目的嵌入,添加的代码如下
<xamlHost:UnoXamlHost InitialTypeName="UnoIslandsSampleApp.MainPage" />
使用上和 WinUI 提供的 Xaml Island 几乎相同。如此即可完成嵌入
完全的 XAML 代码如下
<Window x:Class="TestUnoIslands.Wpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestUnoIslands.Wpf"
mc:Ignorable="d"
xmlns:xamlHost="clr-namespace:Uno.UI.XamlHost.Skia.Wpf;assembly=Uno.UI.XamlHost.Skia.Wpf"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button x:Name="Button" Click="Button_OnClick">Hello from WPF!</Button>
<xamlHost:UnoXamlHost Grid.Row="1"
InitialTypeName="UnoIslandsSampleApp.MainPage" />
</Grid>
</Grid>
</Window>
尝试运行项目,可以看到在一个 WPF 项目里面嵌入了 Uno 的页面
依然的,这个 Uno Islands 技术存在和 WinFormsHost 技术相同的问题,在此矩形范围内,只允许一个 UI 框架工作。被嵌入 Uno 的范围内,不能再次叠加上 WPF 的控件。但我认为这个问题其实也不大,说不定我想不开,或者是某位大佬行行好,就帮他实现了一个可以作为元素插入的功能哈
可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 7ddbfed126c37ec07d5d0d94468f5d0551e122f9
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 7ddbfed126c37ec07d5d0d94468f5d0551e122f9
获取代码之后,进入 TestUnoIslands 文件夹
使用 Uno Islands 在现有 WPF 里面嵌入 Uno 框架的更多相关文章
- WPF中嵌入普通Win32程序的方法
公司现在在研发基于.Net中WPF技术的产品,由于要兼容旧有产品,比如一些旧有的Win32程序.第三方的Win32程序等等,还要实现自动登录这些外部Win32程序,因此必须能够将这些程序整合到我们的系 ...
- WPF中嵌入Office编辑器(支持Word、Excel、PPT、Visio等)
现在有一个项目,需要使用wpf做一个简单的客户端,用来生成word.excel.ppt.visio等文档,这就需要能够在wpf中嵌入office的编辑器,并对office文档进行编辑. 在网上搜索了一 ...
- WPF中嵌入WinForm中的webbrowser控件
原文:WPF中嵌入WinForm中的webbrowser控件 使用VS2008创建WPF应用程序,需使用webbrowser.从工具箱中添加WPF组件中的webbrowser发现其中有很多属性事件不能 ...
- 提供PPT嵌入Winform/WPF解决方案,Winform/WPF 中嵌入 office ppt 解决方案
Winform/WPF 中嵌入 office ppt(powerpoint)解决方案示: 1. 在winform中操作ppt,翻页.播放.退出:显示 总页数.当前播放页数 2. 启动播放ppt时录制视 ...
- 在WPF中嵌入WebBrowser可视化页面
无论是哪种C/S技术,涉及数据可视化就非常的累赘了,当然大神也一定有,只不过面向大多数人,还是通过网页来实现,有的时候不想把这两个功能分开,一般会是客户的原因,所以我们打算在WPF中嵌入WebBrow ...
- 分析现有 WPF / Windows Forms 程序能否顺利迁移到 .NET Core 3.0
本文转自 https://blog.csdn.net/WPwalter/article/details/82859449 使用 .NET Core 3.0 Desktop API Analyzer 分 ...
- 把演讲人的桌面、头像、声音合成后推送到 指定的直播流平台上; 录制电脑桌面、摄像头头像、声音保存为本地视频; 适用于讲课老师、医生等演讲内容保存为视频; 提供PPT嵌入Winform/WPF解决方案,Winform/WPF 中嵌入 office ppt 解决方案
提供PPT嵌入Winform/WPF解决方案,Winform/WPF 中嵌入 office ppt 解决方案 Winform/WPF 中嵌入 office ppt(powerpoint)解决方案示: ...
- 如何实现在react现有项目中嵌入Blazor?
如何实现在react现有项目中嵌入Blazor? 目前官方只提供了angular和react俩种示例所以本教程只将react教程 思路讲解: 首先在现有react项目中我们可能某些组件是在Blazor ...
- 原创:Equinox OSGi应用嵌入Jersey框架搭建REST服务
一.环境 eclipse版本:eclipse-luna 4.4 jre版本:1.8 二.Equinox OSGi应用嵌入Jersey框架搭建REST服务 1.新建插件工程HelloWebOSGI a. ...
- session失效后,登录页面嵌入iframe框架
在登录页面的onload方法中加入以下代码解决: //防止登录页面嵌入iframe框架 if (top.location != self.location){ top.location=self.lo ...
随机推荐
- 记录--vue 拉伸指令
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 在我们项目开发中,经常会有布局拉伸的需求,接下来 让我们一步步用 vue指令 实现这个需求 动手开发 在线体验 codesandbo ...
- win7笔记本、台式机装centos7过程记录
1.国内镜像网站下载centos的iso文件 链接点我: 2.找个u盘,格式化为NTFS格式,这样才能传4G以上大小的文件 3.iso直接复制到u盘是不行的,必须做启动盘.下载个ultra做,官网地 ...
- 内核模块的makefile规则详解
内核中的Makefile 这里主要对内核源码各子集目录中的Kbulid(内核的编译系统)Makfile进行简单介绍 这部分式内核驱动或设备驱动开发这最长接触到的 Makefile 的语法包括几个方面 ...
- 24年3月使用VS22编译Telegram Desktop
0.环境准备,我使用的VS版本是17.9.4,SDK版本是10.0.22621.0,最好不要用太老的版本 1.去下载Python,git,cmake这三个工具,然后在D盘根目录新建TBuild文件夹, ...
- #Splay#U137476 序列
题目 给定长度为\(n\)的序列\(Ai\) ,我们将按照如下操作给\(Ai\) 排序, 先找到编号最小的所在位置\(x1\) ,将\([1,x1]\) 翻转, 再找到编号第二小的所在位置\(x2\) ...
- 80+产品正通过兼容性测试,OpenHarmony生态蓬勃发展
4 月 25 日,开放原子开源基金会举办了 OpenAtom OpenHarmony(以下简称"OpenHarmony")技术日活动,OpenHarmony PMC 委员代表首次对 ...
- 学会在 C++ 中使用变量:从定义到实践
C++ 变量 变量是用于存储数据值的容器. 在 C++ 中,有不同类型的变量(使用不同的关键字定义),例如: int - 存储整数(没有小数点),例如 123 或 -123 double - 存储浮点 ...
- Dev 控件 gridControl教程
Dev 控件 gridControl教程:https://www.bilibili.com/video/BV1gz4y1R7Wk/?spm_id_from=333.788.recommend_more ...
- 财务人提高竞争力必备的技能,怎么能少了ta!
从近年来大数据技术的发展趋势和相关产业飞速发展的状态,可以看出当前"数据分析"的热度可以说是有增无减,而且从市场上对数据分析人才的需求缺口也可以看出企业对数据分析的重视程度.未来随 ...
- mogdb里xlog相关的几个参数
openGauss/MogDB 3.0 闪回恢复测试 本文出处:https://www.modb.pro/db/411368 介绍 闪回恢复功能是数据库恢复技术的一环,可以有选择性的撤销一个已提交事务 ...