Winform窗体应用程序入门
Winform一直以来都是Windows下开发传统GUI应用程序的首选技术,Winform本身也是基于Win32API来封装的,借助强大的Visual Studio IDE,使用Winform开发非常简单,C#和.Net Framework平台拥有优秀的生态,相比直接使用Win32API/MFC来说很多功能都很容易借助.Net平台已有的类库实现。
开始开发Winform工程
打开Visual Studio,创建一个「Windows 窗体应用」。

创建工程时,我们可以根据我们自己的需要选择使用.NET Framework还是新版的.NET Core。不过Winform是个相对较老的框架,使用两种运行时编写的代码基本没有什么区别。
创建完成后,如下图所示,这是一个窗口的界面设计器。我们可以把「工具箱」固定到IDE左侧,方便把控件往窗口上拖拽。右上为我们的工程视图,右下为当前所选空间的属性值,我们可以对其进行编辑。

这里我们先不着急往下做,先看一眼Visual Studio为我们生成的工程目录结构。
LoginDemo
│_ App.config # 存储应用程序配置文件
│_ Form1.cs # 主窗体代码
│_ Form1.Designer.cs # 主窗体代码(设计器)
│_ LoginDemo.csproj # 项目描述文件
│_ Program.cs # 程序入口文件
|_ bin # 编译输出目录
|_ obj # 中间文件目录
|_ Properties # 包含与应用程序的元数据和资源相关的文件
|_ AssemblyInfo.cs # 存放程序集的元数据(如版本信息、描述等)
|_ Resources.resx # 包含了应用程序的资源
|_ Resources.Designer.cs # 包含了应用程序的资源(代码部分)
|_ Settings.settings # 用于管理应用程序的设置
|_ Settings.Designer.cs # 用于管理应用程序的设置(代码部分)
- Form1.cs:其中
Form1就是对应一个窗体的类,我们编写的控件事件处理函数就会写在这里。 - Form1.Designer.cs:该类是一个
Form1的partial class,其内容是Visual Studio设计器为我们自动生成的一些代码,该代码文件是由Visual Studio设计器维护的,除非我们的一些改动造成设计器报错,不然我们应尽量避免手动编辑.Designed.cs文件。 - Resources.resx:它相当于一个资源文件的索引,我们引用的图片等资源就是通过这个配置文件加载的,其内容为XML格式,不过它的具体内容是由Visual Studio维护的,我们不需要关心也不用手动修改。
- Program.cs:程序的入口文件,其中包含
Main()函数。
入口类Program很简单,它初始化了一些参数并实例化Form1窗体类。
using System;
using System.Windows.Forms;
namespace Demo01
{
internal static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
注意对于Winform程序,主线程必须标注[STAThread],这个注解使得主线程使用单线程单元 (Single-Threaded Apartment, STA) 模式,Winform中主线程必须是STA线程。
接下来我们开始窗体设计,我们在设计器中大致拖几个控件进去,组成一个「登录框」。

在右下角中修改各种属性,这个并没有什么难度,Visual Studio中甚至都有属性的中文说明,这里就不展开介绍了。Winform中的属性很多,不认识的可以参考文档。

我们把窗体大致修改成这个样子。

为按钮绑定事件处理函数,可以双击设计器拖进去的按钮控件,这会跳转到按钮的默认事件处理函数,或者点击右下角的闪电图标,双击Click事件,Visual Studio为我们生成了对应的回调函数,其命名规则为控件名_事件名(不是通常的帕斯卡命名法),这个有些奇怪的命名风格是历史原因造成的,我们遵循即可。
private void buttonLogin_Click(object sender, EventArgs e) {}
下面我们假装写一个登录的逻辑。
private void buttonLogin_Click(object sender, EventArgs e)
{
string username = this.textBoxUsername.Text;
string password = this.textBoxPassword.Text;
if(username == "root" && password == "123456")
{
// 登陆成功
MessageBox.Show("登陆成功");
}
else
{
// 登录失败
MessageBox.Show("登陆失败");
}
}
点击「运行」按钮,结果如下。

查看窗体控件大纲
如果我们的界面比较复杂,纯靠设计器可能比较难以理清控件的层次结构。Visual Studio中点击菜单栏视图->其他窗口->文档大纲,我们可以打开控件大纲窗口,方便我们查看当前窗体中的控件层次结构。

我们可以在这个大纲列表中进行点选、删除控件等操作,操作也会反应到设计器主界面中。
使用设计器 vs 纯代码
很多人说学习Winform、Qt等GUI框架时应该避免使用设计器,这是完全错误的观点。设计Winform界面需要调用大量和控件紧密相关的属性和API,这些API我们通常没必要记住,使用设计器能省略这些繁琐的步骤提高开发效率,我们不要“没苦硬吃”。Visual Studio设计器能够帮我们生成界面代码,使用非常方便,它能覆盖绝大部分的需求。
然而,我们并不能说设计器适用于所有场景,当我们需要非常灵活的动态控制控件和事件绑定时,使用设计器就非常不灵活了。此外,对于功能极其复杂的软件,使用纯代码来开发也比设计器更靠谱。
不过在学习阶段,我们还是应该善于使用设计器并分析那些自动生成的样板代码,只要掌握了Winform开发的基本套路,无论使用设计器还是纯代码都不会有太大困难。