一、说明
本篇是系列文章,专门介绍如何用C#上实现窗口和界面程序。值得注意的是,与VC++不同之处在于,VC是纯粹的面向对象,而C#是基于COM接口的编程方法,因此,按照VC++面向对象的MFC的思想无法理解C#,需要建立接口的概念。本篇将实现实验展示,并叙述接口思想。
二、简单窗口实现
2.1 实现简单的窗口工程
假定已经安装好VS2019,然后建立C#的窗口程序。
1 创建新项目
2 选择C#窗口工程
3 给项目起名
然后进入创建窗口,点击【创建】按钮,就可以了。
2.2 窗口工程代码
在 Visual Studio 中创建新表单时,设计器会在 .Designer.cs 文件中生成以下代码:
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
三、以下代码是什么意思?
3.1 关于空窗口的代码
private System.ComponentModel.IContainer components = null;
它是窗体设计器自动生成的代码,作为组件的容器。当窗体上没有组建时,把它删掉, 删了也“无所谓”当窗体上有组件时就不能删了,删了会出现错误的。
也就是:他是管理组件的一个容器。
为了深刻理解,举个例子:
1.新建个窗体,删除了componment,这时没问题的
2.再往窗体拖拽个Timer组件,再看是不是有自动生成了个componment?回答是肯定的。
3.再把componment删了,看看还有没“所谓”,出错了吧!
4.这时其实componment已经不是null了,它已经被new了:this.components = new System.ComponentModel.Container();
components 变量的用途是什么?我的理论是,我应该将它用于我在 Designer 之外创建的表单拥有的任何 IDisposable 类(因为 Dispose 已经由 Designer 实现)。
因此,例如,如果我的表单拥有一种字体,我可以通过将其添加到这样的组件来确保它被处理:
public partial class Form1 : Form
{
Font coolFont;
public Form1()
{
InitializeComponent();
this.coolFont = new Font("Comic Sans", 12);
components.Add(this.coolFont);
}
}
3.2 不可见组件
当您向表单添加非 UI 组件(例如 Timer 组件)时,组件将成为这些组件的父级。设计器文件中的代码确保在处置表单时处置这些组件。如果您没有在设计时将任何此类组件添加到表单中,则组件将为空。
由于组件是设计器生成的,并且如果您在表单上没有非 UI 组件(在设计时),它将为空,我个人会选择以其他方式管理这些组件,将它们放置在表单关闭或类似的东西上。
3.3 其它理解
我试图更深入地理解这一点。我曾尝试在设计时添加组件,但组件实例变量仍然始终为空。如果组件实例变量设置为 null 以外的值,我在哪里可以找到设置它的代码?
我通过添加来自设计器的 SerialPort 组件,在设计器生成的代码中设置组件实例变量。所以我现在明白了。我希望它在不使用时不会生成组件和 Dispose 代码,这样可以避免混淆并减少代码,但是 whatchucando
components 变量等效于表单的 Controls 变量。它跟踪表单上的所有控件。使一个窗体在关闭时可以自动处理所有控件,这是一项非常重要的清理工作。
表单类没有等效的成员来跟踪在设计时放置在其上的所有组件,因此设计人员会自动处理它。
请注意,将 Dispose() 方法从 Designer.cs 文件移动到主表单源代码文件是完全可以接受的。我强烈建议您这样做,没有理由以任何方式使 Form 类“特别”,它只是一个像其他任何类一样的托管类。在 base.Dispose 调用之前添加 Dispose() 调用以根据需要处理成员。
三、基本的控件
我们建立一个基本窗口,该窗口可以打开一个图片文件并显示;而且,可以保存成其它文件名称。如下:
3.1 UI实现步骤
1)首先按照第二节中建立空的窗口。
2)进入UI设计,并从IDE开发环境选【工具】菜单
3)选择三个按钮,改外观后,双击,自动引入空程序代码。
4)填充代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace sharpC_first
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private string pathname = string.Empty;
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog file = new OpenFileDialog();
file.InitialDirectory = ".";
file.Filter = "所有文件(*.*)|*.*";
file.ShowDialog();
if (file.FileName != string.Empty)
{
try
{
pathname = file.FileName; //获得文件的绝对路径
this.pictureBox1.Load(pathname);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private void button2_Click(object sender, EventArgs e)
{
SaveFileDialog save = new SaveFileDialog();
save.ShowDialog();
if (save.FileName != string.Empty)
{
pictureBox1.Image.Save(save.FileName);
}
}
private void button3_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
3.2 测试代码
执行(不调试)菜单的选项,可以执行程序。如下:
1 点击【打开】:出现文件读入对话框。
2 显示如下
小节
我们将以棋盘为例,实现一个可以对弈的象棋程序。下篇博文我们继续实现。
版权归原作者 无水先生 所有, 如有侵权,请联系我们删除。