[演算法2-數組與字元串的查找與匹配] (.NET源碼學習) 關鍵詞:1. 數組查找(演算法) 2. 字元串查找(演算法) 3. C#中的String(源碼) 4. 特性Attribute 與內在屬性(源碼) 5. 字元串的比較(底層原理) 6. C#中的StringComparsion(源碼) 7. 字 ...
隨著 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 文件夾
博客園博客只做備份,博客發佈就不再更新,如果想看最新博客,請到 https://blog.lindexi.com/
本作品採用知識共用署名-非商業性使用-相同方式共用 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發佈,但務必保留文章署名[林德熙](http://blog.csdn.net/lindexi_gd)(包含鏈接:http://blog.csdn.net/lindexi_gd ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我[聯繫](mailto:[email protected])。