.NET Core 3.0 和 3.1 的 Windows 窗体中断性变更

已在 .NET Core 的版本 3.0 中添加 Windows 窗体支持。 本文按引入了中断性变更的 .NET 版本列出了 Windows 窗体的中断性变更。 如果要从 .NET Framework 或 .NET Core 的早期版本(3.0 或更高版本)升级 Windows 窗体应用,本文能为你提供帮助。

本页记录了以下中断性变更:

重大更改 引入的版本
已删除的控件 3.1
如果显示工具提示,则不引发 CellFormatting 事件 3.1
Control.DefaultFont 已更改为 Segoe UI 9 pt 3.0
FolderBrowserDialog 的现代化 3.0
已从一些 Windows 窗体类型中删除 SerializableAttribute 3.0
不支持 AllowUpdateChildControlIndexForTabControls 兼容性开关 3.0
不支持 DomainUpDown.UseLegacyScrolling 兼容性开关 3.0
不支持 DoNotLoadLatestRichEditControl 兼容性开关 3.0
不支持 DoNotSupportSelectAllShortcutInMultilineTextBox 兼容性开关 3.0
不支持 DontSupportReentrantFilterMessage 兼容性开关 3.0
不支持 EnableVisualStyleValidation 兼容性开关 3.0
不支持 UseLegacyContextMenuStripSourceControlValue 兼容性开关 3.0
不支持 UseLegacyImages 兼容性开关 3.0
Visual Basic 的“关于”和“初始屏幕”模板已断开 3.0

.NET Core 3.1

已删除的控件

从 .NET Core 3.1 开始,某些 Windows 窗体控件不再可用。

更改描述

从 .NET Core 3.1 开始,各种 Windows 窗体控件不再可用。 .NET Framework 2.0 中引入改进了设计和支持的替换控件。 弃用的控件之前已从设计器工具箱中删除,但仍可供使用。

以下类型不再可用:

引入的版本

3.1

每个已删除的控件都有一个推荐的替换控件。 请参阅以下表:

已删除的控件 (API) 推荐的替换控件 已删除的关联 API
ContextMenu ContextMenuStrip
DataGrid DataGridView DataGridCell、DataGridRow、DataGridTableCollection、DataGridColumnCollection、DataGridTableStyle、DataGridColumnStyle、DataGridLineStyle、DataGridParentRowsLabel、DataGridParentRowsLabelStyle、DataGridBoolColumn、DataGridTextBox、GridColumnStylesCollection、GridTableStylesCollection、HitTestType
MainMenu MenuStrip
菜单 ToolStripDropDown、ToolStripDropDownMenu MenuItemCollection
MenuItem ToolStripMenuItem
ToolBar ToolStrip ToolBarAppearance
ToolBarButton ToolStripButton ToolBarButtonClickEventArgs、ToolBarButtonClickEventHandler、ToolBarButtonStyle、ToolBarTextAlign

类别

Windows 窗体

受影响的 API


如果显示工具提示,则不引发 CellFormatting 事件

现在,当鼠标悬停和通过键盘选择时,DataGridView 将显示单元格的文本和错误工具提示。 如果显示工具提示,则不会引发 DataGridView.CellFormatting 事件。

更改描述

在 .NET Core 3.1 之前,将 ShowCellToolTips 属性设置为 trueDataGridView 会在鼠标悬停在单元格上方时显示单元格文本和错误的工具提示。 之前,通过键盘选择单元格时(例如通过使用 Tab 键、快捷键或箭头导航),不显示工具提示。 如果用户编辑了单元格,然后在 DataGridView 仍处于编辑模式时将鼠标悬停在未设置 ToolTipText 属性的单元格上,则会引发 CellFormatting 事件,对要在单元格中显示的单元格文本进行格式化。

为满足辅助功能标准,自 .NET Core 3.1 起,将 ShowCellToolTips 属性设置为 trueDataGridView 不仅在鼠标悬停在单元格上时会显示单元格文本和错误的工具提示,而且在通过键盘选择单元格时也会显示。 由于这一变更,如果鼠标在 DataGridView 处于编辑模式时悬停在未设置 ToolTipText 属性的单元格上,不会引发 CellFormatting 事件 。 不引发该事件的原因是鼠标悬停的单元格的内容显示为工具提示,而不是显示在单元格中。

引入的版本

3.1

DataGridView 处于编辑模式时,对依赖 CellFormatting 事件的所有代码进行重构。

类别

Windows 窗体

受影响的 API


.NET Core 3.0

默认控件字体更改为 Segoe UI 9 pt

更改描述

在 .NET Framework 中,Control.DefaultFont 属性设置为 Microsoft Sans Serif 8.25 pt。 下图显示了使用默认字体的窗口。

.NET Framework 中的默认控件字体

从 .NET Core 3.0 开始,默认字体设置为 Segoe UI 9 pt(与 SystemFonts.MessageBoxFont 相同的字体)。 作为此更改的结果,窗体和控件的大小会增加约 27%,以适应新默认字体的更大大小。 例如:

.NET Core 中的默认控件字体

此更改是为了与 Windows 用户体验 (UX) 准则保持一致。

引入的版本

3.0

由于窗体和控件的大小改变,因此请确保应用程序能够正确呈现。

若要保留单个窗体的原始字体,请将其默认字体设置为 Microsoft Sans Serif 8.25 pt。 例如:

public MyForm()
{
    InitializeComponent();
    Font = new Font(new FontFamily("Microsoft Sans Serif"), 8.25f);
}

或者,可以使用以下方法之一更改整个应用程序的默认字体:

  • ApplicationDefaultFont MSBuild 属性设置为“Microsoft Sans Serif,8.25pt”。 这是首选方法,因为它允许 Visual Studio 使用设计器中的新设置。

    <PropertyGroup>
      <ApplicationDefaultFont>Microsoft Sans Serif, 8.25pt</ApplicationDefaultFont>
    </PropertyGroup>
    
  • 通过调用 Application.SetDefaultFont(Font)

    class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.SetHighDpiMode(HighDpiMode.SystemAware);
            Application.SetDefaultFont(new Font(new FontFamily("Microsoft Sans Serif"), 8.25f));
            Application.Run(new Form1());
        }
    }
    

类别

  • Windows 窗体

受影响的 API

无。


FolderBrowserDialog 的现代化

.NET Core 的 Windows 窗体应用程序中的 FolderBrowserDialog 控件已更改。

更改描述

在 .NET Framework 中,Windows 窗体对 FolderBrowserDialog 控件使用以下对话框:

.NET Framework 中的 FolderBrowserDialogControl

在 .NET Core 3.0 中,Windows 窗体使用 Windows Vista 中引入的更新的基于 COM 的控件:

.NET Core 中的 FolderBrowserDialogControl

引入的版本

3.0

此对话框将自动升级。

如果希望保留原始对话框,请在显示对话框之前将 FolderBrowserDialog.AutoUpgradeEnabled 属性设置为 false,如以下代码片段所示:

var dialog = new FolderBrowserDialog();
dialog.AutoUpgradeEnabled = false;
dialog.ShowDialog();

类别

Windows 窗体

受影响的 API


已从一些 Windows 窗体类型中删除 SerializableAttribute

已从一些没有已知二进制序列化方案的 Windows 窗体类中删除 SerializableAttribute

更改描述

下列类型在 .NET Framework 中以 SerializableAttribute 进行修饰,但该属性已在 .NET Core 中删除:

从历史记录来看,此序列化机制存在严重的维护和安全性问题。 保证类型上持续具有 SerializableAttribute 意味着必须针对版本间的序列化更改以及可能出现的框架间序列化更改测试这些类型。 这使得很难发展这些类型且维护成本昂贵。 这些类型没有已知的二进制序列化方案,这在最大限度上消除了删除该属性带来的影响。

有关详细信息,请参阅二进制序列化

引入的版本

3.0

对于要标记为“可序列化”的类型,更新可能依赖它们的所有代码。

类别

Windows 窗体

受影响的 API


不支持 AllowUpdateChildControlIndexForTabControls 兼容性开关

Switch.System.Windows.Forms.AllowUpdateChildControlIndexForTabControls 兼容性开关在 .NET Framework 4.6 及更高版本上的 Windows 窗体中受支持,但在自 .NET Core 或 .NET 5.0 及更高版本中不受支持。

更改描述

在 .NET Framework 4.6 及更高版本中,选中选项卡会对其控件集合重新排序。 借助 Switch.System.Windows.Forms.AllowUpdateChildControlIndexForTabControls 兼容性开关,应用程序可在不需要此类重新排序时跳过此行为。

.NET Core 和 .NET 5.0 及更高版本中尚不支持 Switch.System.Windows.Forms.AllowUpdateChildControlIndexForTabControls 开关。

引入的版本

3.0

删除此开关。 此开关不受支持,且未提供替代功能。

类别

Windows 窗体

受影响的 API


不支持 DomainUpDown.UseLegacyScrolling 兼容性开关

已在 .NET Framework 4.7.1 中引入 Switch.System.Windows.Forms.DomainUpDown.UseLegacyScrolling 兼容性开关,但它在 .NET Core 或 .NET 5.0 及更高版本上的 Windows 窗体中尚不受支持。

更改描述

自 .NET Framework 4.7.1 起,开发人员可使用 Switch.System.Windows.Forms.DomainUpDown.UseLegacyScrolling 兼容性开关选择不执行独立 DomainUpDown.DownButton()DomainUpDown.UpButton() 操作。 该开关会还原旧行为,也就是说如果存在上下文文本,则忽略 DomainUpDown.UpButton()而且开发人员需要先在控件上执行 DomainUpDown.DownButton() 操作,然后才能执行 DomainUpDown.UpButton() 操作。 有关详细信息,请参阅 <AppContextSwitchOverrides> 元素

.NET Core 和 .NET 5.0 及更高版本中尚不支持 Switch.System.Windows.Forms.DomainUpDown.UseLegacyScrolling 开关。

引入的版本

3.0

删除此开关。 此开关不受支持,且未提供替代功能。

类别

Windows 窗体

受影响的 API


不支持 DoNotLoadLatestRichEditControl 兼容性开关

已在 .NET Framework 4.7.1 中引入 Switch.System.Windows.Forms.UseLegacyImages 兼容性开关,但它在 .NET Core 或 .NET 5.0 及更高版本上的 Windows 窗体中尚不受支持。

更改描述

在 .NET Framework 4.6.2 及更低版本中,RichTextBox 控件会实例化 Win32 RichEdit 控件 v3.0;而对于面向 .NET Framework 4.7.1 的应用程序,RichTextBox 控件会实例化 RichEdit v4.1(位于 msftedit.dll 中)。 已引入 Switch.System.Windows.Forms.DoNotLoadLatestRichEditControl 兼容性开关,使面向 .NET Framework 4.7.1 及更高版本的应用程序可选择不使用新的 RichEdit v4.1 控件而改用旧的 RichEdit v3 控件。

.NET Core 和 .NET 5.0 及更高版本中尚不支持 Switch.System.Windows.Forms.DoNotLoadLatestRichEditControl 开关。 仅支持 RichTextBox 控件的新版本。

引入的版本

3.0

删除此开关。 此开关不受支持,且未提供替代功能。

类别

Windows 窗体

受影响的 API


不支持 DoNotSupportSelectAllShortcutInMultilineTextBox 兼容性开关

已在 .NET Framework 4.6.1 中引入 Switch.System.Windows.Forms.DoNotSupportSelectAllShortcutInMultilineTextBox 兼容性开关,但它在 .NET Core 和 .NET 5.0 及更高版本上的 Windows 窗体中尚不受支持。

更改描述

自 .NET Framework 4.6.1 起,在 TextBox 控件中选择 Ctrl + A 快捷键会选中所有文本。 在 .NET Framework 4.6 及更低版本中,如果 Textbox.ShortcutsEnabledTextBox.Multiline 属性都设置为 true,则选择 Ctrl + A 快捷键没法选中全部文本。 为保留原始行为,已在 .NET Framework 4.6.1 中引入 Switch.System.Windows.Forms.DoNotSupportSelectAllShortcutInMultilineTextBox 兼容性开关。 有关更多信息,请参见TextBox.ProcessCmdKey

.NET Core 和 .NET 5.0 及更高版本中尚不支持 Switch.System.Windows.Forms.DoNotSupportSelectAllShortcutInMultilineTextBox 开关。

引入的版本

3.0

删除此开关。 此开关不受支持,且未提供替代功能。

类别

Windows 窗体

受影响的 API


不支持 DontSupportReentrantFilterMessage 兼容性开关

已在 .NET Framework 4.6.1 中引入 Switch.System.Windows.Forms.DontSupportReentrantFilterMessage 兼容性开关,但它在 .NET Core 和 .NET 5.0 及更高版本上的 Windows 窗体中尚不受支持。

更改描述

自 .NET Framework 4.6.1 起,Switch.System.Windows.Forms.DontSupportReentrantFilterMessage 兼容性开关可处理通过自定义 IMessageFilter.PreFilterMessage 实现调用 Application.FilterMessage 消息时可能引发的 IndexOutOfRangeException 异常。 有关详细信息,请参阅缓解:自定义 IMessageFilter.PreFilterMessage 实现

.NET Core 和 .NET 5.0 及更高版本中尚不支持 Switch.System.Windows.Forms.DontSupportReentrantFilterMessage 开关。

引入的版本

3.0

删除此开关。 此开关不受支持,且未提供替代功能。

类别

Windows 窗体

受影响的 API


不支持 EnableVisualStyleValidation 兼容性开关

.NET Core 或 .NET 5.0 及更高版本上的 Windows 窗体不支持 Switch.System.Windows.Forms.EnableVisualStyleValidation 兼容性开关。

更改描述

在 .NET Framework 中,Switch.System.Windows.Forms.EnableVisualStyleValidation 兼容性开关使得应用程序可选择不验证以数值格式提供的视觉样式。

.NET Core 和 .NET 5.0 及更高版本中尚不支持 Switch.System.Windows.Forms.EnableVisualStyleValidation 开关。

引入的版本

3.0

删除此开关。 此开关不受支持,且未提供替代功能。

类别

Windows 窗体

受影响的 API


不支持 UseLegacyContextMenuStripSourceControlValue 兼容性开关

已在 .NET Framework 4.7.2 中引入 Switch.System.Windows.Forms.UseLegacyContextMenuStripSourceControlValue 兼容性开关,但它在 .NET Core 或 .NET 5.0 及更高版本上的 Windows 窗体中尚不受支持。

更改描述

自 .NET Framework 4.7.2 起,开发人员可使用 Switch.System.Windows.Forms.UseLegacyContextMenuStripSourceControlValue 兼容性开关选择退出 ContextMenuStrip.SourceControl 属性的新行为 - 新行为是返回对源控件的引用。 该属性之前的行为是返回 null。 有关详细信息,请参阅 <AppContextSwitchOverrides> 元素

.NET Core 和 .NET 5.0 及更高版本中尚不支持 Switch.System.Windows.Forms.UseLegacyContextMenuStripSourceControlValue 开关。

引入的版本

3.0

删除此开关。 此开关不受支持,且未提供替代功能。

类别

Windows 窗体

受影响的 API


不支持 UseLegacyImages 兼容性开关

已在 .NET Framework 4.8 中引入 Switch.System.Windows.Forms.UseLegacyImages 兼容性开关,但它在 .NET Core 或 .NET 5.0 及更高版本上的 Windows 窗体中尚不受支持。

更改描述

自 .NET Framework 4.8 起,Switch.System.Windows.Forms.UseLegacyImages 兼容性开关会处理高 DPI 环境中 ClickOnce 方案内可能出现的图像缩放问题。 如果设置为 true,则用户可通过此开关在缩放比例设置为大于 100% 的高 DPI 显示器上还原旧的图像缩放行为。 有关详细信息,请参阅 GitHub 上的 .NET Framework 4.8 发行说明

.NET Core 和 .NET 5.0 及更高版本中尚不支持 Switch.System.Windows.Forms.UseLegacyImages 开关。

引入的版本

3.0

删除此开关。 此开关不受支持,且未提供替代功能。

类别

Windows 窗体

受影响的 API


“关于”和“初始屏幕”模板已断开

由 Visual Studio 生成的 About.vbSplashScreen.vb 文件包含对 My 命名空间中不可用的类型(.NET Core 3.0 和 3.1)。

引入的版本

3.0

更改描述

.NET Core 3.0 和 3.1 不包含完整的 Visual Basic My 支持。 Visual Studio for Visual Basic Windows 窗体应用中的“关于”和“初始屏幕”窗体模板引用 My.Application.Info 类型中不可用的属性。

Visual Basic My 支持在 .NET 5 中得以改进,将项目升级到 .NET 5 或更高版本。

-或-

修复应用中“关于”和“初始屏幕”类型的编译器错误。 使用 System.Reflection.Assembly 类获取 My.Application.Info 类型提供的信息。 此处提供了两种窗体的直端口。

提示

这是示例代码,且未进行优化。 应缓存属性列表以减少窗体加载时间。

关于

Imports System.Reflection

Public NotInheritable Class About

    Private Sub about_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Set the title of the form.
        Dim applicationTitle As String = Assembly.GetExecutingAssembly().GetCustomAttribute(Of AssemblyTitleAttribute)()?.Title

        If String.IsNullOrEmpty(applicationTitle) Then
            applicationTitle = System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().GetName().Name)
        End If

        Me.Text = String.Format("About {0}", applicationTitle)
        ' Initialize all of the text displayed on the About Box.
        ' TODO: Customize the application's assembly information in the "Application" pane of the project
        '    properties dialog (under the "Project" menu).
        Me.LabelProductName.Text = If(Assembly.GetExecutingAssembly().GetCustomAttribute(Of AssemblyProductAttribute)()?.Product, "")
        Me.LabelVersion.Text = String.Format("Version {0}", Assembly.GetExecutingAssembly().GetName().Version)
        Me.LabelCopyright.Text = If(Assembly.GetExecutingAssembly().GetCustomAttribute(Of AssemblyCopyrightAttribute)()?.Copyright, "")
        Me.LabelCompanyName.Text = If(Assembly.GetExecutingAssembly().GetCustomAttribute(Of AssemblyCompanyAttribute)()?.Company, "")
        Me.TextBoxDescription.Text = If(Assembly.GetExecutingAssembly().GetCustomAttribute(Of AssemblyDescriptionAttribute)()?.Description, "")
    End Sub

    Private Sub OKButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OKButton.Click
        Me.Close()
    End Sub

End Class

SplashScreen

Imports System.Reflection

Public NotInheritable Class SplashScreen

    Private Sub SplashScreen1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'Set up the dialog text at runtime according to the application's assembly information.  

        'TODO: Customize the application's assembly information in the "Application" pane of the project
        '  properties dialog (under the "Project" menu).

        'Application title
        Dim appTitle As String = Assembly.GetExecutingAssembly().GetCustomAttribute(Of AssemblyTitleAttribute)()?.Title

        If String.IsNullOrEmpty(appTitle) Then
            appTitle = System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().GetName().Name)
        End If

        ApplicationTitle.Text = appTitle

        Dim versionValue = Assembly.GetExecutingAssembly().GetName().Version

        'Format the version information using the text set into the Version control at design time as the
        '  formatting string.  This allows for effective localization if desired.
        '  Build and revision information could be included by using the following code and changing the
        '  Version control's designtime text to "Version {0}.{1:00}.{2}.{3}" or something similar.  See
        '  String.Format() in Help for more information.
        '
        '    Version.Text = System.String.Format(Version.Text, versionValue.Major, versionValue.Minor, versionValue.Build, versionValue.Revision)

        Version.Text = System.String.Format(Version.Text, versionValue.Major, versionValue.Minor)

        'Copyright info
        Copyright.Text = If(Assembly.GetExecutingAssembly().GetCustomAttribute(Of AssemblyCopyrightAttribute)()?.Copyright, "")
    End Sub

End Class

Category

Visual Basic Windows 窗体

受影响的 API


请参阅