C#Windows窗体教程教授使用C#和Windows窗体进行GUI编程的基础知识。在我们的教程中,我们将手动构建我们的应用程序;我们不会使用表单设计器。
窗体
Windows窗体,有时缩写为Winforms,是一种图形用户界面应用程序编程接口(API),包含在Microsoft的.NETFramework中。
Windows窗体允许创建易于部署和更新的图形丰富的应用程序。这些应用程序比传统的基于Windows的应用程序更安全。
2018年12月,Microsoft宣布在GitHub上将WindowsForms作为开源项目发布。它是根据麻省理工学院许可证发布的。在此版本中,Windows窗体已在.NETCore框架上可用。Windows窗体仅在Windows上可用。
构建Windows窗体应用程序
我们将使用.NETCore来创建Windows窗体应用程序。
$ dotnet new winforms -o MyApp
使用dotnetnewwinforms
命令创建Windows窗体应用程序的新模板。
$ dotnet run
应用程序使用dotnetrun
命令运行。
Windows窗体简单示例
在第一个例子中,我们在屏幕上显示一个简单的窗口。
$ dotnet new winforms -o First
我们创建Windows窗体应用程序的模板。该命令还会生成Form1.Designer.cs
和Form1.cs
文件。我们不会使用它们,可以安全地删除它们。
using System.Windows.Forms; using System.Drawing; namespace First { public class MyForm : Form { public MyForm() { InitComponents(); } private void InitComponents() { Text = "First application"; ClientSize = new Size(800, 450); CenterToScreen(); } [STAThread] static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.Run(new MyForm()); } } }
该示例在屏幕上显示一个主窗口。窗口居中。
using System.Windows.Forms; using System.Drawing;
我们使用Windows窗体和绘图命名空间。
public class MyForm : Form { ... }
在Windows窗体中,任何窗口或对话框都是一个窗体。此控件是一个基本容器,其目的是显示其他子控件。MyForm
继承自一个表单。这样它就变成了一种形式。
public MyForm() { InitComponents(); }
作为一种良好的编程习惯,表单初始化委托给InitComponents
方法。
private void InitComponents() { Text = "First application"; ClientSize = new Size(800, 450); CenterToScreen(); }
Text
和Size
是表单的属性。更改这些属性,我们修改我们的表单控件。第一行在表单控件的标题栏中显示文本“Firstapplication”。第二行设置窗体客户区的大小。CenterToScreen
方法使表单在屏幕上居中。
[STAThread] static void Main() { ... }
Main
方法是应用程序的入口点。Windows窗体应用程序必须声明[STAThread]
属性;否则,控件可能无法正常工作。这表明使用单线程单元模型而不是多线程。
Application.SetHighDpiMode(HighDpiMode.SystemAware);
使用SetHighDpiMode
方法,我们确保我们的应用程序在任何显示分辨率下看起来都不错。
Application.EnableVisualStyles();
EnableVisualStyles
方法启用视觉样式。该应用程序将使用内置的Windows主题来设置控件的样式,而不是使用经典的Windows外观。
Application.Run(new MyForm());
Run
方法启动应用程序。它开始在当前线程上运行标准应用程序消息循环,并使指定的表单可见。
Windows窗体工具提示
工具提示是一个小的矩形弹出窗口,当用户将指针放在控件上时,它会显示控件用途的简要说明。
using System.Drawing; using System.Windows.Forms; namespace Tooltips { public class MyForm : Form { private FlowLayoutPanel flowPanel; public MyForm() { InitComponents(); } private void InitComponents() { Text = "Tooltips"; ClientSize = new Size(800, 450); flowPanel = new FlowLayoutPanel(); var ftip = new ToolTip(); ftip.SetToolTip(flowPanel, "This is a FlowLayoutPanel"); flowPanel.Dock = DockStyle.Fill; flowPanel.BorderStyle = BorderStyle.FixedSingle; var button = new Button(); button.Text = "Button"; button.AutoSize = true; var btip = new ToolTip(); btip.SetToolTip(button, "This is a Button Control"); var button2 = new Button(); button2.Text = "Button 2"; button2.AutoSize = true; flowPanel.Controls.Add(button); flowPanel.Controls.Add(button2); Controls.Add(flowPanel); CenterToScreen(); } [STAThread] static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.Run(new MyForm()); } } }
代码示例为两个控件创建了工具提示:一个是Button
控件,另一个是Form
控件。
flowPanel = new FlowLayoutPanel();
我们在FlowLayoutPanel
上放置了两个按钮。它动态地水平或垂直布置其内容。(默认尺寸是垂直的。)
var ftip = new ToolTip(); ftip.SetToolTip(flowPanel, "This is a FlowLayoutPanel");
我们创建了一个新的工具提示。使用SetToolTip
,我们将工具提示分配给FlowLayoutPanel
控件。
flowPanel.Dock = DockStyle.Fill;
FlowLayoutPanel
填充了表单控件的整个区域。
var button = new Button(); button.Text = "Button"; button.AutoSize = true;
创建了一个新的Button
控件。我们使用Text
属性设置它的文本,并自动调整它的大小以适应文本大小。
var btip = new ToolTip(); btip.SetToolTip(button, "This is a Button Control");
工具提示被添加到第一个Button
控件。
flowPanel.Controls.Add(button); flowPanel.Controls.Add(button2); Controls.Add(flowPanel);
按钮添加到流程面板,流程面板添加到表单。
Windows窗体退出按钮
Button
控件表示Windows按钮控件。可以使用鼠标、Enter键或空格键(如果按钮具有焦点)单击它。
using System.Windows.Forms; using System.Drawing; namespace QuitButton { class MyForm : Form { private FlowLayoutPanel flowPanel; public MyForm() { InitComponents(); } private void InitComponents() { Text = "Quit button"; ClientSize = new Size(800, 450); flowPanel = new FlowLayoutPanel(); flowPanel.Dock = DockStyle.Fill; flowPanel.BorderStyle = BorderStyle.FixedSingle; var button = new Button(); button.Margin = new Padding(10, 10, 0, 0); button.Text = "Quit"; button.AutoSize = true; button.Click += (_, _) => Close(); flowPanel.Controls.Add(button); Controls.Add(flowPanel); CenterToScreen(); } [STAThread] static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.Run(new MyForm()); } } }
该示例创建了一个退出按钮控件;当我们点击按钮时,应用程序终止。
var button = new Button(); button.Margin = new Padding(10, 10, 0, 0);
按钮的边框周围有一些边距。我们在按钮控件的左侧和上方添加了一些空间。
button.Click += (_, _) => Close();
我们将事件处理程序插入到Click
事件中。当我们单击该按钮时,应用程序将使用Close
方法关闭。由于我们不使用发送者对象和事件参数,所以我们使用丢弃。
Windows窗体标签
Label
是一个用于显示文本或图像的简单控件。它没有获得焦点。
using System.Drawing; using System.Windows.Forms; namespace LabelEx { public class MyForm : Form { public MyForm() { InitUI(); } private void InitUI() { string text = @" Spending my time Watching the days go by Feeling so small, I stare at the wall Hoping that you think of me too I'm spending my time I try to call but I don't know what to tell you I leave a kiss on your answering machine Oh, help me please, is there someone who can make me Wake up from this dream? "; var font = new Font("Serif", 10); var lyrics = new Label(); lyrics.Parent = this; lyrics.Text = text; lyrics.Font = font; lyrics.Location = new Point(10, 10); lyrics.AutoSize = true; CenterToScreen(); Text = "Label"; AutoSize = true; CenterToScreen(); } [STAThread] static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.Run(new MyForm()); } } }
该示例使用Label
控件显示歌词。
var font = new Font("Serif", 10);
我们使用这种字体来显示文本。
var lyrics = new Label(); lyrics.Parent = this; lyrics.Text = text; lyrics.Font = font; lyrics.Location = new Point(10, 10); lyrics.AutoSize = true;
标签控件已创建。它位于窗体上的x=10,y=10坐标。
Text = "Label"; AutoSize = true; CenterToScreen();
主窗口会自动调整大小以适合歌词。
Windows窗体复选框
CheckBox
是一个具有两种状态的控件:打开和关闭。它是一个带有标签或图像的盒子。如果CheckBox
被选中,则用框中的勾号表示。
using System.Windows.Forms; using System.Drawing; namespace CheckBoxEx { class MyForm : Form { private FlowLayoutPanel FlowPanel; public MyForm() { InitUI(); } private void InitUI() { Text = "CheckBox"; ClientSize = new Size(450, 250); FlowPanel = new FlowLayoutPanel(); var pad = new Padding(20); var cb = new CheckBox(); cb.Margin = pad; cb.Parent = this; cb.Text = "Show Title"; cb.AutoSize = true; cb.Checked = true; cb.CheckedChanged += new EventHandler(OnChanged); FlowPanel.Controls.Add(cb); Controls.Add(FlowPanel); CenterToScreen(); } void OnChanged(object sender, EventArgs e) { if (((CheckBox )sender).Checked) { Text = "CheckBox"; } else { Text = ""; } } [STAThread] static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.Run(new MyForm()); } } }
代码示例根据窗口的状态显示或隐藏窗口的标题。
var pad = new Padding(20); cb = new CheckBox(); cb.Margin = pad; cb.Parent = this; cb.Text = "Show Title"; cb.AutoSize = true; cb.Checked = true;
当应用程序启动时,我们会显示标题。我们将CheckBox
控件设置为选中状态。
cb.CheckedChanged += new EventHandler(OnChanged);
当我们点击CheckBox
控件时,CheckedChanged
事件被触发。
void OnChanged(object sender, EventArgs e) { if (((CheckBox )sender).Checked) { Text = "CheckBox"; } else { Text = ""; } }
根据Checked
属性的值,我们切换窗口的标题。
Windows窗体简单菜单
菜单栏是菜单的集合。菜单对应用程序的命令进行分组。
using System.Drawing; using System.Windows.Forms; namespace MenuEx { class MyForm : Form { public MyForm() { Text = "Simple menu"; var ms = new MenuStrip(); ms.Parent = this; var fileMenuItem = new ToolStripMenuItem("&File"); var exitMenuItem = new ToolStripMenuItem("&Exit", null, (_, _) => Close()); exitMenuItem.ShortcutKeys = Keys.Control | Keys.X; fileMenuItem.DropDownItems.Add(exitMenuItem); ms.Items.Add(fileMenuItem); MainMenuStrip = ms; ClientSize = new Size(450, 300); CenterToScreen(); } [STAThread] static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.Run(new MyForm()); } } }
在我们的示例中,我们有一个菜单栏和一个菜单。在菜单中有一个菜单项。如果我们选择菜单项,应用程序将关闭。
也可以使用Ctrl+X快捷方式或按Alt、F关闭应用程序,E键。
var ms = new MenuStrip();
MenuStrip
为我们的表单创建一个菜单系统。我们将ToolStripMenuItem
对象添加到代表菜单结构中各个菜单命令的MenuStrip。每个ToolStripMenuItem
都可以是应用程序的命令或其他子菜单项的父菜单。
var fileMenuItem = new ToolStripMenuItem("&File");
这里我们使用ToolStripMenuItem
创建一个菜单。
var exitMenuItem = new ToolStripMenuItem("&Exit", null, (_, _) => Close());
此行创建退出菜单项。
exitMenuItem.ShortcutKeys = Keys.Control | Keys.X;
我们为退出菜单项提供了快捷方式。
fileMenuItem.DropDownItems.Add(exitMenuItem);
退出菜单项被添加到菜单对象的下拉项中。
ms.Items.Add(fileMenuItem);
这里我们将菜单对象添加到菜单条中。
MainMenuStrip = ms;
MenuStrip
被插入到窗体中。换句话说,菜单栏被添加到应用程序的主窗口。
Windows窗体绘制矩形
绘画是使用Windows窗体提供的绘画API完成的。绘画是在一个方法中完成的,我们将其插入到Paint
事件中。
using System.Drawing; using System.Windows.Forms; namespace RectanglesEx { class Program : Form { public Program() { InitUI(); } private void InitUI() { Text = "Rectangles"; Paint += new PaintEventHandler(OnPaint); ClientSize = new Size(550, 450); CenterToScreen(); } void OnPaint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.FillRectangle(Brushes.Sienna, 10, 15, 90, 60); g.FillRectangle(Brushes.Green, 130, 15, 90, 60); g.FillRectangle(Brushes.Maroon, 250, 15, 90, 60); g.FillRectangle(Brushes.Chocolate, 10, 105, 90, 60); g.FillRectangle(Brushes.Gray, 130, 105, 90, 60); g.FillRectangle(Brushes.Coral, 250, 105, 90, 60); g.FillRectangle(Brushes.Brown, 10, 195, 90, 60); g.FillRectangle(Brushes.Teal, 130, 195, 90, 60); g.FillRectangle(Brushes.Goldenrod, 250, 195, 90, 60); } [STAThread] static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.Run(new Program()); } } }
我们用九种不同的颜色绘制九个矩形。
Paint += new PaintEventHandler(OnPaint);
Paint事件被传送到OnPaint
方法。
void OnPaint(object sender, PaintEventArgs e) { ... }
这是OnPaint
方法的签名。
Graphics g = e.Graphics;
为了在窗体上绘画,我们必须得到Graphics
对象。在窗体上绘画实际上就是调用Graphics
对象的各种方法。
g.FillRectangle(Brushes.Sienna, 10, 15, 90, 60);
FillRectagle
方法用画笔填充指定的矩形。画笔可以是一种颜色或一种图案。有一些预定义的颜色可用。我们可以从Brushes
枚举中获取它们。最后四个值分别是左上角的x、y值和矩形的宽高。
在本文中,我们使用C#和Windows窗体创建了简单的GUI应用程序。
阅读C#教程或列出所有C#教程。