這是教學課程的第一個部分,示範如何將名為 Contoso Expenses 的範例 WPF 傳統型應用程式現代化。 如需教學課程的概觀、先決條件和下載範例應用程式的指示,請參閱 教學課程:將 WPF 應用程式現代化。
在本教學課程的這個部分中,您會將整個 Contoso Expenses 應用程式從 .NET Framework 4.7.2 移轉至 .NET Core 3。 開始本教學課程的這個部分之前,請確定您已在Visual Studio 2019 中 開啟並建置 ContosoExpenses 範例 。
備註
如需將 WPF 應用程式從 .NET Framework 移轉至 .NET Core 3 的詳細資訊,請參閱 此部落格系列。
將 ContosoExpenses 專案移轉至 .NET Core 3
在本節中,您會將 Contoso Expenses 應用程式中的 ContosoExpenses 專案移轉至 .NET Core 3。 您將建立新的項目檔,其中包含與現有 ContosoExpenses 專案相同的檔案,但以 .NET Core 3 為目標,而不是 .NET Framework 4.7.2。 這可讓您使用 .NET Framework 和 .NET Core 版本的應用程式維護單一解決方案。
確認 ContosoExpenses 專案目前以 .NET Framework 4.7.2 為目標。 在 [方案總管] 中,按一下滑鼠右鍵 ContosoExpenses 專案,選擇 [屬性],然後確認 [應用程式] 標籤上的 [目標平台] 屬性已設定為 .NET Framework 4.7.2。
針對專案 的 .NET Framework 4.7.2 版
在 Windows 檔案總管中,流覽至 C:\WinAppsModernizationWorkshop\Lab\Exercise1\01-Start\ContosoExpenses 資料夾,並建立名為 ContosoExpenses.Core.csproj 的新文本檔。
以滑鼠右鍵按兩下檔案,選擇 [[使用開啟],然後在您選擇的文本編輯器中開啟它,例如 [記事本]、[Visual Studio Code] 或 [Visual Studio]。
將下列文字複製到檔案並加以儲存。
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <UseWPF>true</UseWPF> </PropertyGroup> </Project>關閉檔案並返回Visual Studio中的 ContosoExpenses 方案。
以滑鼠右鍵點擊 ContosoExpenses 方案,然後選擇 [新增-> 現有專案]。 選取您剛才在 資料夾中建立
C:\WinAppsModernizationWorkshop\Lab\Exercise1\01-Start\ContosoExpenses檔案,將其新增至解決方案。
ContosoExpenses.Core.csproj 包含下列元素:
- Project 元素會指定 Microsoft.NET.Sdk.WindowsDesktop 的 SDK 版本。 這是指適用於 Windows 桌面的 .NET 應用程式,其中包含 WPF 和 Windows Forms 應用程式的元件。
- PropertyGroup 元素包含子元素,指出專案輸出為可執行檔(而非 DLL),以 .NET Core 3 為目標,並使用 WPF。 針對 Windows Forms 應用程式,您會使用 UseWinForms 元素,而不是 UseWPF 元素。
備註
使用 .NET Core 3.0 引進的 .csproj 格式時,與 .csproj 相同資料夾中的所有檔案都會被視為專案的一部分。 因此,您不需要指定專案中包含的每個檔案。 您只能指定要定義自訂建置動作或要排除的檔案。
將 ContosoExpenses.Data 專案遷移至 .NET Standard
ContosoExpenses 解決方案包含一個面向 .NET 4.7.2 的 ContosoExpenses.Data 類函式庫,其中包含服務的模型和介面。 只要 .NET Core 3.0 應用程式不使用 .NET Core 中無法使用的 API,就可以使用 .NET Framework 連結庫。 不過,最佳的現代化途徑是將您的程式庫移至 .NET Standard。 這將確保您的程式庫完全由 .NET Core 3.0 應用程式支援。 此外,您可以將該程式庫重複使用於其他平台,如網路平台(透過 ASP.NET Core)。
若要將 ContosoExpenses.Data 專案移轉至 .NET Standard:
在 Visual Studio 中,以滑鼠右鍵點擊 ContosoExpenses.Data 項目,然後選擇 卸除專案。 再次以滑鼠右鍵按兩下項目,然後選擇 [編輯 ContosoExpenses.Data.csproj]。
刪除項目檔的整個內容。
複製並貼上下列的 XML,然後儲存檔案。
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> </Project>以滑鼠右鍵點擊 ContosoExpenses.Data 項目,然後選擇 [重載專案]。
設定 NuGet 套件和相依性
當您在前一部分移轉 ContosoExpenses.Core 和 ContosoExpenses.Data 專案時,您已經從專案中移除了 NuGet 套件的參考。 在本節中,您會將這些參考加入回去。
若要設定 ContosoExpenses.Data 專案的 NuGet 套件:
在 ContosoExpenses.Data 專案中,展開 相依性 節點。 請注意,缺少了 NuGet 區段。
當您在 [方案總管] 中開啟 Packages.config 時,您會發現專案使用完整 .NET Framework 時所用之 NuGet 套件的「舊」參考。
以下是 Packages.config 檔案的內容。 您會發現所有 NuGet 套件都以完整 .NET Framework 4.7.2 為目標:
<?xml version="1.0" encoding="utf-8"?> <packages> <package id="Bogus" version="26.0.2" targetFramework="net472" /> <package id="LiteDB" version="4.1.4" targetFramework="net472" /> </packages>在 ContosoExpenses.Data 專案中,刪除 Packages.config 檔案。
在 ContosoExpenses.Data 專案中,右鍵點擊 [相依性] 節點,然後選擇 [管理 NuGet 套件]。
在 [NuGet 套件管理員] 視窗中,按兩下 [流覽]。 搜尋
Bogus套件並安裝最新的穩定版本。
搜尋
LiteDB套件並安裝最新的穩定版本。
您可能想知道這些 NuGet 套件清單的儲存位置,因為專案不再有 packages.config 檔案。 參考的 NuGet 套件會直接儲存在 .csproj 檔案中。 您可以使用文本編輯器檢視 ContosoExpenses.Data.csproj 專案檔的內容來進行檢查。 您會發現在檔案結尾新增的下列幾行:
<ItemGroup> <PackageReference Include="Bogus" Version="26.0.2" /> <PackageReference Include="LiteDB" Version="4.1.4" /> </ItemGroup>備註
您可能會注意到,您正在為此 .NET Core 3 專案安裝的套件與 .NET Framework 4.7.2 專案所使用的套件是相同的。 NuGet 套件支援多重目標。 連結庫作者可以在相同套件中包含不同版本的連結庫,這些版本會針對不同的架構和平臺進行編譯。 這些套件支援與 .NET Core 3 專案相容的完整 .NET Framework 和 .NET Standard 2.0。 如需 .NET Framework、.NET Core 和 .NET Standard 差異的詳細資訊,請參閱 .NET Standard。
若要設定 ContosoExpenses.Core 專案的 NuGet 套件:
在 ContosoExpenses.Core 專案中,開啟 packages.config 檔案。 請注意,目前它包含以下以 .NET Framework 4.7.2 為目標的參考。
<?xml version="1.0" encoding="utf-8"?> <packages> <package id="CommonServiceLocator" version="2.0.2" targetFramework="net472" /> <package id="MvvmLightLibs" version="5.4.1.1" targetFramework="net472" /> <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" /> <package id="Unity" version="5.10.2" targetFramework="net472" /> </packages>在下列步驟中,您將看到
MvvmLightLibs和Unity套件的 .NET Standard 版本。 另外兩個是當您安裝這兩個函式庫時,NuGet 會自動下載的相依元件。在 ContosoExpenses.Core 專案中,刪除 Packages.config 檔案。
以滑鼠右鍵點擊 ContosoExpenses.Core 項目,然後選擇 [管理 NuGet 套件]。
在 [NuGet 套件管理員] 視窗中,按兩下 [流覽]。 搜尋
Unity套件並安裝最新的穩定版本。
搜尋
MvvmLightLibsStd10套件並安裝最新的穩定版本。 這是套件的MvvmLightLibs.NET Standard 版本。 針對此套件,作者選擇將連結庫的 .NET Standard 版本封裝在與 .NET Framework 版本不同的套件中。
在 ContosoExpenses.Core 專案中,以滑鼠右鍵點擊 [依賴性] 節點,然後選擇 [新增參考]。
在 [專案 > 方案] 類別中,選取 [ContosoExpenses.Data],然後點擊 [確定]。
停用自動產生的元件屬性
在移轉過程中,如果您嘗試建置 ContosoExpenses.Core 專案,您可能會看到一些錯誤。
之所以發生此問題,是因為 .NET Core 3.0 引進的新 .csproj 格式會將元件資訊儲存在項目檔中,而不是 AssemblyInfo.cs 檔中。 若要修正這些錯誤,請停用此行為,並讓專案繼續使用 AssemblyInfo.cs 檔案。
在 Visual Studio 中,以滑鼠右鍵按一下 ContosoExpenses.Core 專案,然後選擇 [卸除專案]。 再次以滑鼠右鍵點擊專案,然後選擇 [編輯 ContosoExpenses.Core.csproj]。
在 PropertyGroup 區段中新增下列元素,並儲存檔案。
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>新增此元素之後, PropertyGroup 區段現在看起來應該像這樣:
<PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <UseWPF>true</UseWPF> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> </PropertyGroup>以滑鼠右鍵按兩下
ContosoExpenses.Core 項目,然後選擇 [重載專案]。 以滑鼠右鍵點擊 ContosoExpenses.Data 專案,然後選擇 [卸除專案]。 再次以滑鼠右鍵按兩下項目,然後選擇 [編輯 ContosoExpenses.Data.csproj]。
在 PropertyGroup 區段中新增相同的項目,並儲存檔案。
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>新增此元素之後, PropertyGroup 區段現在看起來應該像這樣:
<PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> </PropertyGroup>以滑鼠右鍵點擊 ContosoExpenses.Data 項目,然後選擇 [重載專案]。
新增 Windows 相容性套件
如果您現在嘗試編譯 ContosoExpenses.Core 和 ContosoExpenses.Data 專案,您會看到先前的錯誤已經修正,但 ContosoExpenses.Data 程式庫中仍有一些類似的錯誤。
Services\RegistryService.cs(9,26,9,34): error CS0103: The name 'Registry' does not exist in the current context
Services\RegistryService.cs(12,26,12,34): error CS0103: The name 'Registry' does not exist in the current context
Services\RegistryService.cs(12,97,12,123): error CS0103: The name 'RegistryKeyPermissionCheck' does not exist in the current context
這些錯誤是將 ContosoExpenses.Data 專案從 .NET Framework 連結庫(適用於 Windows 專用)轉換為 .NET Standard 連結庫的結果,這些連結庫可以在 Linux、Android、iOS 等多個平臺上執行。 ContosoExpenses.Data 專案包含名為 RegistryService 的類別,該類別會與登錄互動,這是僅限 Windows 的概念。
若要解決這些錯誤,請安裝 Windows 相容性 NuGet 套件。 此套件支援許多 Windows 特定 API,以用於 .NET Standard 連結庫。 使用此套件後,該程式庫將不再支援跨平臺,但仍以 .NET Standard 為目標。
以滑鼠右鍵點擊 ContosoExpenses.Data 專案。
選擇 管理 NuGet 套件。
在 [NuGet 套件管理員] 視窗中,按兩下 [流覽]。 搜尋
Microsoft.Windows.Compatibility套件並安裝最新的穩定版本。
現在,再次嘗試編譯專案,方法是以滑鼠右鍵按兩下
ContosoExpenses.Data 項目,然後選擇 [建置]。
這次建置程式將會完成,而不會發生錯誤。
測試和偵錯移轉
既然專案建置成功,您就可以開始執行並測試應用程式,以查看是否有任何運行時錯誤。
以滑鼠右鍵點擊 ContosoExpenses.Core 專案,然後選擇 設定為啟動專案。
按 F5 以在調試程式中啟動 ContosoExpenses.Core 專案。 您會看到類似下列的例外狀況。
之所以引發這個例外狀況,是因為當您在移轉開始時從 .csproj 檔案中刪除內容時,您移除了映射檔的 建置動作 相關信息。 下列步驟會修正此問題。
停止偵錯工具。
以滑鼠右鍵點擊 ContosoExpenses.Core 專案,然後選擇 卸載專案。 再次以滑鼠右鍵點擊專案,然後選擇 [編輯 ContosoExpenses.Core.csproj]。
在結束 Project 元素之前,新增下列項目:
<ItemGroup> <Content Include="Images/*"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup>以滑鼠右鍵按兩下
ContosoExpenses.Core 項目,然後選擇 [重載專案]。 若要將Contoso.ico指派給應用程式,請以滑鼠右鍵按下 ContosoExpenses.Core 專案,然後選擇 [ 屬性]。 在開啟的頁面中,點擊 [圖示] 下方的下拉選單 [],然後選擇 [
Images\contoso.ico]。專案屬性 中的
Contoso 圖示 點選 [儲存]。
按 F5 以在調試程式中啟動 ContosoExpenses.Core 專案。 確認應用程式現在執行。
後續步驟
在本教學課程中,您已成功將 Contoso Expenses 應用程式移轉至 .NET Core 3。 您現在已準備好 第 2 部分:使用 XAML Islands新增 UWP InkCanvas 控制項。
備註
如果您有高解析度畫面,您可能會注意到應用程式看起來非常小。 您將在教學課程的下一個步驟中解決此問題。