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#教程。
