閱讀本文,你可以了解如何編寫開發和調試 XAML 構建為 Baml 和 g.cs 文件的過程和工具。本文也適合想要了解 WPF 的 XAML 構建過程的開發者閱讀,本文提供了可以斷點調試 WPF 的 XAML 構建過程的方法和代碼
本文非新手友好,有大量構建和預編譯知識,請在閱讀本文之前自行了解這部分知識。更多請看 手把手教你寫 Roslyn 修改編譯
在 WPF 中,構建 XAML 用的是 PresentationBuildTasks 任務進行構建,核心使用的是 dotnet sdk 提供的構建調度功能,將 XAML 的構建調度到 PresentationBuildTasks 任務,由此工具進行構建。使用 PresentationBuildTasks 任務可以構建出 Baml 和 g.cs 等文件
在 WPF 開源倉庫里面,包含了 PresentationBuildTasks 的所有源代碼。在 dotnet sdk 里面,包含了調試 XAML 構建的后門,允許開發者指定 PresentationBuildTasks 為自己的開發版本
下面以調試 Walterlv.Demo.XamlProperties 測試項目的 XAML 構建過程作為例子,告訴大家如何讓 dotnet 在構建 WPF 項目時,使用自定義的 PresentationBuildTasks 任務進行構建
先在 Walterlv.Demo.XamlProperties.csproj 文件里面添加如下代碼
<PropertyGroup>
<_PresentationBuildTasksTfm Condition="'$(MSBuildRuntimeType)' == 'Core'">netcoreapp2.1</_PresentationBuildTasksTfm>
<_PresentationBuildTasksTfm Condition="'$(MSBuildRuntimeType)' != 'Core'">net472</_PresentationBuildTasksTfm>
<_PresentationBuildTasksAssembly>$(MSBuildThisFileDirectory)..\PresentationBuildTasks\bin\Debug\$(_PresentationBuildTasksTfm)\PresentationBuildTasks.dll</_PresentationBuildTasksAssembly>
</PropertyGroup>
以上的代碼的 _PresentationBuildTasksAssembly
屬性需要修改為你自己的 PresentationBuildTasks 代碼構建出來的輸出文件路徑。在 dotnet 里面,如果在 VisualStudio 里面,那么將加載 .NET Framework 4.7.2 版本的 PresentationBuildTasks.dll 的文件。如果是在命令行執行 dotnet build 命令,此時將加載 .NET Core 2.1 的 PresentationBuildTasks.dll 的文件。此部分知識請參閱 從零開始制作 NuGet 源代碼包(全面支持 .NET Core / .NET Framework / WPF 項目) - walterlv 和 在項目文件 / MSBuild / NuGet 包中編寫擴展編譯的時候,正確使用 props 文件和 targets 文件 - walterlv 和 如何創建一個基於 MSBuild Task 的跨平台的 NuGet 工具包 - walterlv
而 PresentationBuildTasks 的代碼可以從 WPF 開源倉庫里面的 src\Microsoft.DotNet.Wpf\src\PresentationBuildTasks
文件夾拿到代碼,只是這里面的代碼構建需要做一些配置
我給大家提供了我的版本,此版本包含了 Walterlv.Demo.XamlProperties 測試項目本身,使用方法是將我的代碼拉到你的本地。請在使用時,安裝好 .NET 5 或更新版本的 SDK 然后將你的需要測試的 XAML 文件和代碼加入到 Walterlv.Demo.XamlProperties 測試項目里面。先打開 PresentationBuildTasks.sln 項目,接着使用命令行 dotnet build 構建 Walterlv.Demo.XamlProperties 測試項目
構建時將會彈出 VisualStudio 附加進程調試窗口,選擇使用 PresentationBuildTasks.sln 所在的 VisualStudio 進行調試,下一步按下 F10 就可以看到 PresentationBuildTasks 的源代碼
獲取以上調試版本的方法是先創建一個本地源代碼文件夾,此文件夾是一個空文件夾,用來從 GitHub 上拉我的代碼。先使用命令行進入到此空文件夾,接下來輸入以下代碼用來拉代碼
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin e9982404d4b51f184f483ba8663ee160befdc8e8
以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源
git remote add origin https://github.com/lindexi/lindexi_gd.git
以上代碼包含了作為測試項目的 Walterlv.Demo.XamlProperties.csproj 文件,以及我從 WPF 項目里面拷貝的 PresentationBuildTasks 代碼。對比放在 WPF 項目的 PresentationBuildTasks 的代碼,我提供的測試代碼是沒有 WPF 項目的依賴的,不僅構建方便,同時構建速度也快
當然缺點是沒有更上 WPF 的源代碼版本,需要大家自己手動去拷貝最新的代碼
本文提供的代碼,其實是准備調試 AttachedProperty cannot be assigned in a XAML file if it is declared in the same project. · Issue #4544 · dotnet/wpf
歡迎大家參與 WPF 框架的開發
當前的 WPF 在 https://github.com/dotnet/wpf 完全開源,使用友好的 MIT 協議,意味着允許任何人任何組織和企業任意處置,包括使用,復制,修改,合並,發表,分發,再授權,或者銷售。在倉庫里面包含了完全的構建邏輯,只需要本地的網絡足夠好(因為需要下載一堆構建工具),即可進行本地構建