接下来,本公众号会继续《C#与.NET Framework开发》合集的发布,主要介绍基于Windows系统和.NET Framework环境下的Windows窗体应用开发;测试环境为Windows 10和.NET Framework 4.0,开发工具继续使用Visual Studio Community 2019。
请注意,Windows窗体(Form)是.NET Framework中的术语,实际上,“窗体”就是Windows操作系统中的窗口;所以,以下不会严格区分“窗体”和“窗口”术语,如果没有特殊说明,它们的含义是相同的。
测试中会创建一个名为“WinFormDemo”的Windows窗体应用(应用类型如下图所示)。
测试代码的解决方案名称为“chyxlib”,其中还会包含一些代码封装项目,如Windows窗体应用开发的通用代码库“chyxlib”(与解决方案同名)、操作SQLite3数据库的“chyx.datax.sqlitex”项目,这些项目的类型为“类库(.NET Framework)”,如下图所示。
回到“WinFormDemo”项目,根据模板创建的项目会自动添加Program.cs文件和Form1窗体。Program.cs文件是项目的主代码文件,其中,Program类中的Main()静态方法是程序的入口方法,可以在这里进行应用的初始化等操作,可以看到,其中会以Form1的实例作为启动窗口,如下面的代码。
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace WinFormDemo { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } }
实际应用中,可以根据需要启动指定的窗体,如欢迎界面、用户登录等。
在“解决方案资源管理器”中双击打开Form1窗体,可以看到一个空白的窗体设计界面,通过窗体右键菜单“属性”项可以打开属性窗口,下图显示了“属性”窗口的主要组成部分。
下面了解窗体(Form)的一些常用属性。
(Name)属性,窗体的类名。一般会在创建时指定。
AutoScaleMode属性,窗体的自动缩放模式。应用运行时,不同的操作系统(如Windows7、Windows 10、Windows 11等),以及不同的系统缩放比例(如100%、125%、150%等)情况下,窗体的显示效果都是不同的,而AutoScaleMode属性会指定窗体的自动缩放方式;默认的属性值是Font,其他属性值有Dpi、Inherit和None。实际工作中应对可能的应用环境进行全面测试,以观察在不同系统、分辨率及缩放比例时的显示效果。本系列文章中会统一使用None属性值。
ControlBox属性,设置是否显示窗口控制按钮(即标题栏右侧的最小化、最大化/正常、关闭按钮)。MaximizeBox和MinimizeBox属性分别指定是否显示最大化和最小化按钮。
Font属性,设置窗体中显示文本的字体。
ForeColor属性,设置文本的颜色。BackColor属性设置背景色,即窗体显示的颜色。
Icon属性,设置窗体的图标。ShowIcon属性指定是否显示图标。
Opacity属性,设置窗体的不透明度。100%为完全不透明,0%为完全透明。TransparencyKey属性设置显示透明的颜色。
ShowInTaskbar属性,设置是否显示在任务栏上,默认为true。
Size属性,指定窗体的初始尺寸,其中包括宽度(Width)和高度(Height)值,单位为像素。
StartPosition属性,指定窗体的初始位置,默认为WindowsDefaultLocation,其他属性有Manual、CenterScreen、WindowsDefaultBounds、CenterParent。程序启动后的第一个界面如果不是最大化,一般会显示在屏幕中间,即设置为CenterScreen。
Text属性,设置标题栏中显示的文本。
TopMost属性,默认为false,设置为true时,窗口总是显示在其他窗口之上,如悬浮窗口、快捷操作图标等。应注意,其他窗口的TopMost应设置为false。
WindowsState属性,设置窗口的初始状态,默认为正常(Normal),还可以设置为最小化(Minimized)或最大化(Maximized)。
窗体中,最常见的事件(event)是Load,即窗体载入时触发的事件,在这里可以进行窗体的初始化操作。鼠标双击窗体的空白处即可打开代码编辑窗口,此时会自动创建Load事件的响应方法,如下列代码所示。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WinFormDemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // } } }
代码中,Form1_Load()方法就是Form1窗体Load事件的响应方法,在这里可以添加一些初始化代码。那么,此方法是如何关联到Form1窗体的Load事件呢?实际上,Form1窗体中的一些自动完成的代码定义在Form1.Designer.cs文件中,其中可以看到Form1窗体的Load事件与Form1_Load()方法的关联代码,如下所示。
this.Load += new System.EventHandler(this.Form1_Load);
一般来讲,*.Designer.cs文件中的代码不需要手工修改。事件是由委托实现的,而窗体的Load事件类型则是System.EventHandler委托类型,使用+=运算符将Form1_Load方法添加到委托序列中。
查看Form1窗体的其它事件时,可以打开窗体设计界面,然后在“属性”窗口中点击“事件”按钮,如下图所示。
可以看到,Load事件中已有对应响应方法。
窗体中,FormClosed事件会在窗体关闭后触发,可以进行一些资源的清理等操作,在“属性”窗口的事件列表中双击事件名称即可以自动添加事件响应方法代码。这里可以关注FormClosing事件,此事件会在窗体关闭前触发,这里可以有机会阻止窗体的关闭;双击FormClosing事件,然后在Form1_FormClosing()方法中添加如下代码。
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (MessageBox.Show("真的要退出吗", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) { e.Cancel = true; } }
点击工具栏“执行”按钮或键盘F5运行程序。在关闭Form1窗体时会弹出一个问题对话框,如下图的所示。
这里,选择“是”会关闭Form1窗口并退出应用,点击“否”时会将e参数(FormClosingEventArgs类型)的Cancel属性设置为true,此时会阻止窗口的关闭操作。
这里,应用测试主要关注两个问题:
测试中,Debug和Release模式生成的文件分别位于项目所在位置的Bin目录中的Debug和Release目录,生成的程序执行文件(.exe)主要的区别是:Debug版本的执行文件会包含一些调试信息,其尺寸会比Release模式的执行文件稍大一些。开发过程中,应选择Debug模式,可以更好定位错误,以便进行修改和优化。开发完成后,可以选择Release模式进行测试,其运行效果更高;此外,Release模式下的文件还可以直接打包发布(需要同时包含必要的组件)。
大多数情况下,基于.NET Framework的应用可以同时兼容32位和64位平台,但对于某些第三方组件则可能严格区分32位或64位平台,所以,在使用这些组件时则需要在对应的平台上进行更多的测试;发布使用了这些第三方组件的程序时,同样需要包含对应的基于32位或64位平台的组件。