支持使用基於Windows窗體應用程序的.NET Core 3.0(預覽)的Windows窗體設計器
介紹
截至撰寫本文時,Microsoft和社區目前正在測試.NET Core 3.0。如果您在.NET Core 3.0的一般可用性之后閱讀本文,請跳過本文。否則,繼續。
Windows Forms一直是維護企業/企業桌面應用程序的巔峰之作。盡管有着開發桌面應用程序的古老機制,但微軟能夠認識到經過實戰測試的工具包的優勢,並決定將其轉移到現代.NET Core平台(以前稱為.NET Framework)。
到目前為止,他們設法通過Windows窗體轉換很好地將事物整合在一起,但是缺少早期采用者的一些關鍵組件,其中一個恰好是Windows窗體設計器; Microsoft Visual Studio內置的工具,旨在簡化用戶界面開發。要確認.NET Core 3.0預覽中的Windows窗體設計器限制,請嘗試打開並設計任何表單/用戶控制文件(通常是新創建的項目中的Form1.cs。)因此,文章的結果存在。本文將指導您如何克服.NET Core 3.0預覽版Windows窗體設計器的限制,而無需等待其一般可用性。
軟件要求
要繼續閱讀本文,您必須在系統上安裝以下組件:
- Microsoft Visual Studio 2019 - 至少版本16.2.0
- .NET Core 3.0預覽版7(截至編寫本文時,將使用預覽版7)
克服限制
證明問題
- 創建一個新的Windows窗體應用程序(.NET Core)。如果您看不到左側的條目,請使用方便的“ 搜索模板”搜索框並鍵入“ Windows Forms App(.NET Core) ”。
- 對於這個項目,我們將命名它
DotNetCore.WinForms
,但你可以任意命名,確保理解這個概念,你會很高興。 - 如果沒有進行任何更改,請嘗試打開Form1.cs
此時,您開始感覺到在.NET Core 3.0預覽下無法進行任何類型的用戶界面設計。
解決方案
為了解決這個限制,我們可以使用一種方法,通過基於功能齊全的.NET Framework創建一個額外的Windows Forms項目,我們可以間接地利用.NET Core項目的設計。請繼續直到最后。
- 右鍵單擊解決方案名稱,然后創建一個名為_TemporaryFixup的新解決方案文件夾。
- 在_TemporaryFixup解決方案文件夾下,創建一個新的Windows窗體應用程序(.NET Framework)項目。如果您看不到左側的條目,請使用方便的“ 搜索模板 ”搜索框並鍵入“ Windows Forms App(.NET Framework) ”。
- 對於這個項目,我們將命名為DotNetFramework.WinForms,但您可以將其命名為任何您喜歡的名稱。
- 刪除Form1.cs
- 右鍵單擊該
DotNetFramework.WinForms
項目,然后單擊“ 屬性”。 - 將默認命名空間更改為與.NET Core項目相同; 在我們的例子中,我們將其設置為
DotNetCore.WinForms
(將在幾個中解釋) - 創建一個新表單並將其命名為您喜歡的任何名稱。
現在,讓我們使用以下命令修改項目中的Program.cs文件DotNetFramework.WinForms
:
1 using System; 2 using System.IO; 3 using System.Linq; 4 5 namespace DotNetFramework.WinForms 6 { 7 static class Program 8 { 9 private static string SourceProjectDir = 10 @"C:\Users\ahmad\source\repos\DotNetCore.WinForms\DotNetFramework.WinForms"; 11 private static string TargetProjectDir = 12 @"C:\Users\ahmad\source\repos\DotNetCore.WinForms\DotNetCore.WinForms"; 13 14 [STAThread] 15 static void Main() 16 { 17 var directory = new DirectoryInfo(SourceProjectDir); 18 19 var srcFiles = directory.GetFiles("*.Designer.cs", SearchOption.AllDirectories); 20 21 foreach (var srcFile in srcFiles) 22 { 23 // Get the relative directory 24 var relativeDirectory = $"{srcFile.DirectoryName.Substring 25 (SourceProjectDir.Length, 26 srcFile.DirectoryName.Length - SourceProjectDir.Length)}"; 27 28 // Append the determined relative directory to the corresponding designer 29 // & C# source files related to the form. 30 var designerFileName = $@"{relativeDirectory}\{srcFile.Name}"; 31 var noDesignerFileName = 32 $@"{relativeDirectory}\{srcFile.Name.Replace(".Designer", "")}"; 33 34 var srcDesignerFile = $"{SourceProjectDir}{designerFileName}"; 35 var srcNoDesignerFile = $"{SourceProjectDir}{noDesignerFileName}"; 36 37 var dstDesignerFile = $"{TargetProjectDir}{designerFileName}"; 38 var dstNoDesignerFile = $"{TargetProjectDir}{noDesignerFileName}"; 39 40 // Create an array based on the relative location. 41 var dirs = relativeDirectory.Split('\\').ToList(); 42 43 // Keep track of where were we when we created a directory. 44 var currentDir = TargetProjectDir; 45 46 // Start creating the missing directories in our target project. 47 foreach (var dir in dirs) 48 { 49 currentDir = Path.Combine(currentDir, dir); 50 Directory.CreateDirectory(currentDir); 51 } 52 53 // Overwrite the file to the targeted project. 54 File.Copy(srcDesignerFile, dstDesignerFile, true); 55 56 // If our UI logic is unavailable, that means we've created 57 // a new form from the source project. 58 // so we copy the form's UI logic code to the target project. 59 if (!File.Exists(dstNoDesignerFile) && File.Exists(srcNoDesignerFile)) 60 { 61 File.Copy(srcNoDesignerFile, dstNoDesignerFile, false); 62 } 63 } 64 } 65 } 66 }
由於我們專注於在.NET Core平台上開發我們的應用程序,因此我們不需要顯示.NET Framework對應的任何對話框。我們寧願*只將.NET Framework項目的用戶界面設計部分反映到.NET Core項目中。這幾乎可以解釋為什么我們之前將默認命名空間更改為.NET Framework項目,還記得嗎?
確保修改SourceProjectDir
變量以保存.NET Framework項目目錄,並使用TargetProjectDir
變量保存.NET Core項目目錄。
接下來,我們想要在每次構建和運行.NET Core項目時調出.NET Framework可執行文件。在我們繼續前進之前,首先構建整個解決方案。其次,右鍵單擊.NET Framework項目並單擊Properties,然后從左側的選項卡中選擇Build Events。在“ 預構建事件命令行 ”字段中,粘貼以下內容:
1 $(TargetPath)
最后,您可以從.NET Framework項目開始設計用戶界面元素,並通過按Ctrl + Shift + B自動反映您對.NET Core項目的更改,然后運行!
使用代碼
上面提供的代碼本質上是一個反射器。它僅反映.NET Framework項目的.NET Framework項目的表單文件。您可以無限制地修改代碼,使其按照您的意圖執行操作。
興趣點
Windows窗體設計器的便利性已被帶回。無論您是計划在.NET Core下使用Windows Forms重新開始,還是遷移現有的基於.NET Framework的傳統項目,您現在都可以輕松地繼續這樣做,而無需等待.NET Core 3.0的一般可用性。