隨著 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:
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" >
<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 的控制元件,但我認為這個問題其實也不大,說不定我想不開,或者是某位大佬行行好,就幫他實作了一個可以作為元素插入的功能哈
本文的代碼放在github 和 gitee 歡迎訪問
可以通過如下方式獲取本文的源代碼,先創建一個空檔案夾,接著使用命令列 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 檔案夾
博客園博客只做備份,博客發布就不再更新,如果想看最新博客,請到 https://blog.lindexi.com/

本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可,歡迎轉載、使用、重新發布,但務必保留文章署名[林德熙](http://blog.csdn.net/lindexi_gd)(包含鏈接:http://blog.csdn.net/lindexi_gd ),不得用于商業目的,基于本文修改后的作品務必以相同的許可發布,如有任何疑問,請與我[聯系](mailto:[email protected]),
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/509805.html
標籤:WPF
上一篇:使用 Uno Islands 在現有 WPF 里面嵌入 Uno 框架
下一篇:將結構陣列傳遞給C中的函式
