在 .NET Core 3.0 预览版中使用 Windows Forms 设计器





5.00/5 (5投票s)
一个教程,它允许为基于 .NET Core 3.0(预览版)的 Windows Forms 应用程序使用 Windows Forms 设计器
引言
截至本文撰写之时,微软和社区正在测试 .NET Core 3.0。如果您在 .NET Core 3.0 正式发布后阅读本文,请跳过此文章。否则,请继续阅读。
如果视频框不显示,请访问 此链接 观看本文的完整演示。
Windows Forms 一直是维护业务/企业桌面应用程序的巅峰之作。尽管其开发桌面应用程序的机制有些过时,但微软能够认识到这个经过实战检验的工具包的优势,并决定将其迁移到现代的 .NET Core 平台(以前称为 .NET Framework)。
到目前为止,他们在 Windows Forms 的迁移方面做得相当不错,但对于早期采用者来说,一些关键组件仍然缺失,其中之一就是 Windows Forms 设计器;它是 Microsoft Visual Studio 内置的一个工具,旨在简化用户界面开发。要认识到 .NET Core 3.0 预览版中 Windows Forms 设计器的局限性,请尝试打开并设计任何窗体/用户控件文件(通常是新创建项目中的 Form1.cs)。因此,本文应运而生。本文将引导您如何克服 .NET Core 3.0 预览版 Windows Forms 设计器的局限性,而无需等到其正式发布。
软件要求
为了能够跟随本文进行操作,您必须在系统中安装以下组件
- Microsoft Visual Studio 2019 - 至少 16.2.0 版本
- .NET Core 3.0 预览版 7(截至本文撰写之时,将使用预览版 7)
克服限制
演示问题
- 创建一个新的 Windows Forms 应用程序(.NET Core)。如果左侧看不到该选项,请使用方便的“搜索模板”搜索框并输入“Windows Forms App (.NET Core)”。
- 对于此项目,我们将将其命名为
DotNetCore.WinForms
,但您可以根据需要命名,只要理解概念即可。 - 在未做任何更改之前,尝试打开 Form1.cs 文件,您应该会看到类似这样的内容。请不要惊慌,这是因为我们正在运行 .NET Core 3.0 的预览版本,这是正常现象。稍后我们将解决这个问题。
此时,您开始感觉到在 .NET Core 3.0 预览版下无法进行任何用户界面设计。
解决方案
为了绕过此限制,我们可以采用一种方法,即通过创建一个基于功能齐全的 .NET Framework 的附加 Windows Forms 项目,来间接访问 .NET Core 项目的设计。请继续阅读。
- 右键单击解决方案名称,创建一个名为 _TemporaryFixup 的新解决方案文件夹。
- 在 _TemporaryFixup 解决方案文件夹下,创建一个新的 **Windows Forms 应用程序(.NET Framework)**项目。如果左侧看不到该选项,请使用方便的“搜索模板”搜索框并输入“Windows Forms App (.NET Framework)”。
- 对于此项目,我们将将其命名为 DotNetFramework.WinForms,但您可以根据需要命名。
- 删除 Form1.cs 文件。
- 右键单击
DotNetFramework.WinForms
项目,然后单击“属性”。 - 将默认命名空间更改为与 .NET Core 项目相同;在本例中,我们将将其设置为
DotNetCore.WinForms
(稍后会解释)。 - 创建一个新窗体,并将其命名为任意名称。
现在,让我们修改 DotNetFramework.WinForms
项目中的 Program.cs 文件,如下所示:
using System;
using System.IO;
using System.Linq;
namespace DotNetFramework.WinForms
{
static class Program
{
private static string SourceProjectDir =
@"C:\Users\ahmad\source\repos\DotNetCore.WinForms\DotNetFramework.WinForms";
private static string TargetProjectDir =
@"C:\Users\ahmad\source\repos\DotNetCore.WinForms\DotNetCore.WinForms";
[STAThread]
static void Main()
{
var directory = new DirectoryInfo(SourceProjectDir);
var srcFiles = directory.GetFiles("*.Designer.cs", SearchOption.AllDirectories);
foreach (var srcFile in srcFiles)
{
// Get the relative directory
var relativeDirectory = $"{srcFile.DirectoryName.Substring
(SourceProjectDir.Length,
srcFile.DirectoryName.Length - SourceProjectDir.Length)}";
// Append the determined relative directory to the corresponding designer
// & C# source files related to the form.
var designerFileName = $@"{relativeDirectory}\{srcFile.Name}";
var noDesignerFileName =
$@"{relativeDirectory}\{srcFile.Name.Replace(".Designer", "")}";
var srcDesignerFile = $"{SourceProjectDir}{designerFileName}";
var srcNoDesignerFile = $"{SourceProjectDir}{noDesignerFileName}";
var dstDesignerFile = $"{TargetProjectDir}{designerFileName}";
var dstNoDesignerFile = $"{TargetProjectDir}{noDesignerFileName}";
// Create an array based on the relative location.
var dirs = relativeDirectory.Split('\\').ToList();
// Keep track of where were we when we created a directory.
var currentDir = TargetProjectDir;
// Start creating the missing directories in our target project.
foreach (var dir in dirs)
{
currentDir = Path.Combine(currentDir, dir);
Directory.CreateDirectory(currentDir);
}
// Overwrite the file to the targeted project.
File.Copy(srcDesignerFile, dstDesignerFile, true);
// If our UI logic is unavailable, that means we've created
// a new form from the source project.
// so we copy the form's UI logic code to the target project.
if (!File.Exists(dstNoDesignerFile) && File.Exists(srcNoDesignerFile))
{
File.Copy(srcNoDesignerFile, dstNoDesignerFile, false);
}
}
}
}
}
由于我们专注于在 .NET Core 平台上开发应用程序,因此我们不需要显示来自 .NET Framework 对应项目的任何对话框。我们宁愿仅将 .NET Framework 项目的用户界面设计部分“**反射**”到 .NET Core 项目中。这基本上解释了为什么我们之前将 .NET Framework 项目的默认命名空间更改了,还记得吗?
请确保修改 SourceProjectDir
变量以包含您的 .NET Framework 项目目录,并将 TargetProjectDir
变量设置为 .NET Core 项目目录。
接下来,我们希望在每次要生成和运行 .NET Core 项目时调用 .NET Framework 可执行文件。在我们继续之前,请先生成整个解决方案。然后,右键单击 **.NET Framework 项目**,单击“属性”,然后从左侧的选项卡中选择“生成事件”。在“生成前事件命令行”字段中,粘贴以下内容:
$(TargetPath)
最后,您可以开始从 .NET Framework 项目设计用户界面元素,并通过按 **Ctrl+Shift+B** 然后运行,从而自动将更改反映到 .NET Core 项目!
Using the Code
上面提供的代码本质上是一个反射器。它仅将 .NET Framework 项目的窗体文件反射到 .NET Core 项目。您可以无限制地修改代码,使其实现您的预期功能。
关注点
Windows Forms 设计器的便利性已回归。无论您是计划在 .NET Core 下从头开始开发 Windows Forms,还是迁移现有的传统 .NET Framework 项目,您现在都可以轻松进行,而无需等待 .NET Core 3.0 正式发布。
历史
- 版本 1.0 - 初始提交
- 版本 1.0.1 - 添加了 YouTube 视频链接进行演示