更新 WinForms | InitializeComponent 的现代代码生成

news2024/11/18 13:35:59

当你使用 Visual Studio 中的 WinForms Designer 来创建一个 WinForms 表单或用户控件时,它并没有像 XML 或 HTML 那样的特殊定义或文件格式来表示用户界面。从一开始,WinForms 使用的唯一格式就是程序代码。在 WinForms Visual Basic 项目中定义的表单或用户控件会被保存到 VB 代码中。在 C# 项目中,这就是 C# 代码。这些代码将被放置在一个专用的 Designer 文件中,该文件位于实际表单代码文件后面,也包含控制 UI 的代码。

当你的表单或用户控件需要在 WinForms Designer 中再次打开时,该代码将被解释并根据结果对象图在 Designer 中重新创建表单/用户控件。这就是我们把保存表单的过程称为 CodeDOM 序列化的原因。这里的 CodeDOM 指的是一种对象模型(Code Document object model,代码文档对象模型),它允许开发人员通过特定类型的对象来定义程序的各个方面或程序的一部分。

虽然 CodeDOM 很灵活,可以比较容易地进行扩展,并且支持比 Visual Basic 或 C# 更多的语言,但是从现有的代码文件生成 CodeDOM 图是一件完全不同的事情。虽然 CodeDOM 可以通过现有的编译器实现为特定的语言编写代码文件,但生成的代码风格仍然是 .NET 框架刚开始时的风格,在许多情况下已经不再符合当前的编码标准。

在 WinForms 中,当你设计一个表单的时候,所有相关的内容都是在每个表单或用户控件的一个方法中生成的。这个方法(还有一些基础结构和初始化代码)叫做 InitializeComponent。

这个方法会被表单的构造函数无条件地调用。在 C# 中,这是非常明显的,你添加到项目中的新表单总是具有构造函数和所需的调用:

public partial class Form1 : Form    {        public Form2()        {            InitializeComponent();        }    }

在 Visual Basic 中,如果你不显式地添加构造函数 Sub New,Visual Basic 编译器会在后台自动插入对 InitializeComponent 的调用。但如果你在代码文件中添加了一个构造函数,编辑器也会在 VB 代码中插入对 InitializeComponent 的调用:

Public Class Form1
    Sub New()
        ' This call is required by the designer.        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.
    End SubEnd Class

注意,在 Visual Basic 中,Inherits 语句允许新表单类继承 System.Windows.Forms.Form 基类,与 C# 不同的是,它只是 Designer 代码隐藏文件的一部分。在 VB 中,分部类只需在其中一个分部类的代码文件中声明 partial 关键字即可。这就是为什么 Visual Basic WinForms 表单代码文件默认不包含任何东西,只包含表单的类定义的原因。

直到最近,WinForms Designer 使用 CodeModel 接口来解释不同编码语言的源代码,以构建所需的内部 CodeDOM 图,以便 Designer 保存表单或用户控件的定义。但是我们改变了这一点。

Enter Roslyn

WinForms 在 Visual Studio 2022 17.5版本中引入了一种现代化的方式,来读取和生成 WinForms 进程外 Designer 的 InitializeComponent 代码。它通过使用 .NET 编译器平台的 API(通常称为 Roslyn SDK)来完成所有相关任务。Roslyn 编译器是一套针对 .NET 语言的开源编译器和代码分析 API。它允许开发人员使用现代语言特性在 C# 和 Visual basic .NET 中编写、分析和操作代码。它还提供了一套丰富的诊断和代码重构功能,以提高代码质量和开发人员的工作效率。它是 C# 和 VB 代码生成的黄金标准和当前的最佳实践。而且,由于它与 Visual Studio 中用于编译和构建任何 C# 或 Visual Basic 项目的工具相同,因此其代码生成结果完全符合当前的编码标准。

此外,由于 Roslyn 编译器提供了某些  API,不仅知道特定语句、命令或方法的正确语法,而且还知道在 WinForms 设计时代码块的语义,WinForms Designer 可以比以前更早、更精确地指出 InitializeComponent 内部代码潜在的问题。因此,它不仅知道你什么时候拼错了“Buttne”——它还知道在 InitializeComponent 内部定义的拼写错误的变量将是一个未知的符号,并且能够指出这一点。

但是还有一系列额外的好处:

  • 以前,基于 CodeModel 构建 CodeDOM 只能在 UI Thread 上运行。这不仅是一种阻塞操作,而且无法充分发挥现代多核处理器的潜力。使用 Roslyn 编译器,我们将可以通过使用并行化来优化构建的过程。

  • 旧的系统没有一种简单的方法来解释最近引入的语言特性。而使用 Roslyn,我们可以选择引入像 NameOf 这样的语言特性来生成更优的代码,特别是用于数据绑定的时候。此外,它为未来 InitializeComponent 内部更复杂的代码生成开辟了新的道路,这将有助于优化和均衡在具有不同 HighDPI 设置的机器上的 HighDPI 场景的代码生成。

  • Roslyn 编译器支持许多方面的 .editorconfig 配置,因此在 InitializeComponent 中生成的代码接近于您和您的团队通过自定义 .editorconfig 定义强制执行的编码标准。

总而言之,有一些编码元素与之前的有本质上的不同。C# 中 this 或 Visual Basic 中 Me 的省略就是一个例子。下面的截图显示了 Roslyn 在 InitializeComponent 中 Button 的代码生成的区别:

如果你对将 WinForms Designer 中的代码生成转移到 Roslyn 或如何使用 .editorconfig 配置 InitializeComponent 代码生成的更多技术背景感兴趣,请查看 WinForms 库中的这篇技术文章,它更详细地解释了所有这些内容。

关于这个主题的反馈对我们来说真的很重要,请在文章下方留言告诉我们你在 WinForms 代码生成方面的想法或意见。如果你对 WinForms Designer 有任何建议,或者发现了一个 bug,请随时在 WinForms Github 库中提交新的 issue。编码愉快!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/445091.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ONES 联合中国信通院发布《中国企业软件研发管理白皮书》

4月20日,由 ONES 与中国信通院联合发起的《中国企业软件研发管理白皮书》发布会暨「软件质效沙龙一北京站」正式举行。发布会上,ONES 与中国信通院云计算与大数据研究所的各位领导、行业专家及众多软件从业者一起,聚焦研发管理热点动态&#…

【hello C++】内存管理

目录 前言: 1. C/C内存分布 2. C语言动态内存管理方式 3. C内存管理方式 3.1 new / delete 操作内置类型 3.2 new和delete操作自定义类型 4. operator new与operator delete函数 4.1 operator new与operator delete函数 5. new和delete的实现原理 5.1 内置类型 5.2…

杭州乐芯CNC 机器人采集方法汇总

杭州乐芯CNC数据采集方法及支持的系统 一,杭州乐芯CNC 机器人采集方法汇总 1,采用SDK开发包采集,比如发那科 FANUC \三菱 、海德汉、大隈OKUMA(O-API)、华中数控、凯恩帝、沙迪克、牧野电火花、台湾宝元、上海来钠克…

怎么把avi文件转换成mp4视频格式,4个高能方法

怎么把avi文件转换成mp4视频格式? 当您下载到avi格式的视频文件时,您可能会选择将其转换为MP4格式的文件。 avi是一种由微软开发的多媒体容器格式,尽管现在已经被认为是老旧的技术,但由于其简单易懂的开发API和Windows的通用性&am…

【CSS3】CSS3 2D 转换 - rotate 旋转 ② ( 使用 rotate 旋转绘制三角形 )

文章目录 一、使用 rotate 旋转绘制三角形二、代码示例 一、使用 rotate 旋转绘制三角形 使用 rotate 旋转绘制三角形 的原理 : 先绘制正方形 , 为该正方形设置边框 , 只设置 右侧 和 下方的 边框 , div {width: 40px;height: 40px;border-right: 2px solid black;border-bott…

tmux---linux终端复用器使用

tmux---linux终端复用器使用 tmux 介绍安装使用tmux会话管理新建会话分离会话接入会话杀死会话切换会话重命名会话 窗格操作划分窗格移动光标交换窗格位置窗格快捷键 tmux 介绍 命令行的典型使用方式是,打开一个终端窗口(terminal window,以…

发令枪音效芯片,语音提示ic

发令枪属于管制物品,只能在运动员训练或比赛时使用,其余时间段不能使用,更不能在非比赛场地公众场合使用。在径赛、游泳比赛等开始时,主要是用来发出声音信号的器械,形状像手枪。 电子发令枪,采用电子元器…

Baklib最佳实践:如何设计符合用户需求的FAQ页面?

在当今互联网时代,随着信息量的不断增加和用户信息获取方式的多样化,越来越多的公司、组织和个人开始创建自己的FAQ页面。作为一个企业或组织的“门面”,FAQ页面对于提升品牌形象、提高服务质量以及吸引潜在客户等方面都起着至关重要的作用。…

传统机器学习(三)聚类算法K-means(一)

传统机器学习(三)聚类算法K-means(一) 一、聚类算法K-means初识 1.1 算法概述 K-Means算法是无监督的聚类算法,它实现起来比较简单,聚类效果也不错,因此应用很广泛。K-Means基于欧式距离认为两个目标距离越近,相似度越大。 1.…

详解C语言string.h中常见的14个库函数(二)

本篇博客继续讲解string.h中的库函数。在上一篇博客中,我介绍了strlen, strcpy, strcat, strcmp这4个字符串操作函数,本篇博客会继续介绍strncpy, strncat, strncmp这3个类似的函数。 strcpy, strcat, strcmp这3个函数是长度不受限制的字符串操作函数&a…

ubuntu安装V2board宝塔面板教程

ubuntu安装V2board宝塔面板教程 运行环境:ubuntu-20.04 搭建宝塔web页面环境 切到linux服务器命令行 在用户目录下创建BT目录,进入BT目录 在BT目录下执行命令 sudo wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo sh install.sh…

考虑梯水电站群的水火电节能调度(Python代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

oracle rac 安装文档

oracle rac 安装文档 一、前期准备1.1 操作系统centos 7.4 *2台,要求双网卡1.2 主机名:oracle01,oracle021.3 数据库版本:oracle 11g rac1.4 空间要求:1.4.1 系统:(系统使用磁盘)1.4…

python基于mediapipe开发构建人体姿态检测系统

之前做的人体姿态检测大都是基于openpose或者是yolo-pose之类的技术框架,这里主要是想基于一个开源的实现来完成人体姿态检测。首先看下效果图: Mediapipe是google的一个开源项目,支持跨平台的常用ML方案。项目在这里,如下所示&am…

软件挖掘|软件缺陷|蜕变关系

目录 软件无处不在 软件发展不是一个简单的任务 识别软件缺陷 软件缺陷定位 使用bug报告识别有缺陷的源代码 使用标准IR方法建模相关性 VSM rVSM 根据bug报告和源代码学习共享主题,并根据主题衡量相关度 学习结合大量手工制作的特性 如何建模&#xf…

页表结构详细说明

一、页表 1. 内存地址的分解 我们知道linux采用了分页机制,通常采用四级页表,页全局目录(PGD),页上级目录(PUD),页中间目录(PMD),页表(PTE)。如下: 其含义定义在arch/arm64/include/asm/pgtable-hwdef.…

应急响应 - Windows启动项分析,Windows计划任务分析,Windows服务分析

「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 Windows应急响应 一、启动项分析1、msconfig2、gpedit.msc3、注册表4、msinfo325、启动菜…

【数据结构实验】哈希表设计

【数据结构实验】哈希表设计 简介 针对本班同学中的人名设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。文末贴出了源代码。 需求分析 假设人名为中国人姓名的汉语拼音形式,待填入哈希表的人名共有三十个左右&#x…

汇编指令角度掌握函数调用堆栈详细过程

函数参数从右向左依次压栈push,call 要先把下一行指令 压栈, 根据如下代码思考两个问题: 问题一:main函数调用sum,sum执行完以后,怎么知道回到哪个函数中? 问题二:sum函数执行完&…

使用树状图可视化聚类

一般情况下,我们都是使用散点图进行聚类可视化,但是某些的聚类算法可视化时散点图并不理想,所以在这篇文章中,我们介绍如何使用树状图(Dendrograms)对我们的聚类结果进行可视化。 树状图 树状图是显示对象…