目录
一、什么是WinForm
二、WinForm项目结构
三、窗口设计与控件布局
四、窗口事件
五、比较一下Winform和WPS之间的区别是什么?
六、Winform模式实现MVC架构
一、什么是WinForm
WinForm 是 Windows Form 的简称,是基于 .NET Framework 平台的客户端(PC软件)开发技术,一般使用 C# 编程。在VS2019中,C# WinForm 编程需要创建「Windows窗体应用程序」项目。Windows 窗体应用程序是 C# 语言中的一个重要应用,也是 C# 语言最常见的应用。使用 C# 语言编写的 Windows 应用程序与 Windows 操作系统的界面类似,每个界面都是由窗体构成的,并且能通过鼠标单击、键盘输入等操作完成相应的功能。WinForm支持可视化设计,简单易上手,并可以接入大量的第三方UI库或自定义控件,给桌面应用开发带来了无限可能。
二、WinForm项目结构
(1)引用:包括所有的系统库文件的引用依赖
(2)App.config:当前项目的配置文件
(3)Form1.cs:当前窗体的事件逻辑源码
Form1.Designer.cs:当前窗体的控件布局源码
Form1.resx:当前窗体的资源文件(图片、图标、资源等)
三、窗口设计与控件布局
操作:在设计界面拖拽控件,可以完成界面布局(控件大小、名称、类型、样式等)
原理:设计界面自动关联Form1.Designer.cs文件,在InitializeComponent()方法中会自动生成相关代码
设计原则:Form1.Designer.cs文件:窗体控件布局文件,一般【不需要我们修改】,只要通过设计界面代码就会自动生成。 Form1.cs文件:窗体事件逻辑代码的实现,一般【需要我们手动书写】,包括触发事件、回调、数据交互、跳转等等
手动添加控件:不通过设计界面,有两种方式
四、窗口事件
(1)操作:在设计界面-控件属性-闪电符号(事件)-添加事件,就会在Form1.cs中自动生成该 控件相应方法名称的事件触发函数
(2) MessageBox.Show():显示弹出消息提示框
(3)GUI界面下Console.WriteLine不显示,需要使用调试模式
五、比较一下Winform和WPS之间的区别是什么?
比较基础 | Winform | WPF |
进步 | Winform是开发桌面应用程序的旧概念 | WPF 是用于开发应用程序的先进或最新概念 |
简单的 | Winform易于使用,因为控件可以轻松使用。 | 与 Windows 窗体相比,WPF 使用起来很复杂。 |
可扩展 | 如果以后需要扩展 UI 元素,Winform的可扩展性就会降低。 | WPF 对于应用程序中的 UI 元素具有广泛的可扩展性 |
安全的 | Winform的安全功能较低 | WPF 具有增强的安全功能。 |
设计 | 在需要设计的地方不使用 Winform | WPF主要用于设计应用程序的UI部分 |
表现 | 在 Winform中,事情的完成速度较慢。 | 在 WPF 中,事情主要以相对非常快的速度实现。 |
六、Winform模式实现MVC架构
称它为MVP模式,MVC模式主要解决的问题就是将表示层和业务层进行分离,在以往做WINFORM项目的时候,通常都是将很多的逻辑代码直接写在了Form.cs代码的事件里,这样的话业务逻辑就和界面紧耦合在一起了,采用MVC来解耦。
首先建立Model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace WindowsFormsApplication10
{
public class Person : INotifyPropertyChanged
{
private string _id;
public string ID
{
get { return _id; }
set { _id = value; OnPropertyChanged("ID"); }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; OnPropertyChanged("Name"); }
}
#region INotifyPropertyChanged 成员
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string PropertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(PropertyName));
}
}
#endregion
}
}
为了能支持双向绑定数据,Model实现了INotifyPropertyChanged接口.
再看看Controllor的实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsFormsApplication10
{
public class PersonControllor
{
public PersonForm View;
public Person Model;
public PersonControllor(PersonForm view)
{
//初始化了一个Model
Model = new Person() { ID = "1", Name = "xiaojun" };
//通过构造函数将View注入到Controllor中
this.View = view;
//建立起View 和Controllor的关联
//这时候View中能使用它所对应的Controllor进行业务逻辑的操作,Model也能和VIEW UI控件进行双向绑定
this.View.Controllor = this;
}
/// <summary>
/// 执行一个业务逻辑
/// </summary>
public void UpdatePerson()
{
UpdateToDataBase(Model);
}
private void UpdateToDataBase(Person p)
{
//do some thing
//执行将数据插入到数据库的操作
System.Windows.Forms.MessageBox.Show("ID:" + p.ID + " Name:" + p.Name);
}
}
}
然后是View的实现:
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 WindowsFormsApplication10
{
public partial class PersonForm : Form
{
private PersonControllor _controllor;
public PersonControllor Controllor
{
get { return _controllor; }
set
{
this._controllor = value;
//绑定一定只能写在给Controllor赋值以后而不能写在PersonForm的构造函数中(此时Controllor还未被实例化)
//因为我们这里采用的是Controllor-First而不是View-First,不然Controllor.Model为null会异常
//将View通过构造函数注入到Controllor中的属于Controllor-First,这时候Controllor先创建
//将Controllor通过构造函数注入到View中的属于View-First,这时候View先创建
this.textBox1.DataBindings.Add("Text", Controllor.Model, "ID");
this.textBox2.DataBindings.Add("Text", Controllor.Model, "Name");
}
}
public PersonForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//改变VIEW的UI控件的值,Controllor的Model会跟着变
this.textBox1.Text = "2";
this.textBox2.Text = "jacky";
Controllor.UpdatePerson();
}
private void button2_Click(object sender, EventArgs e)
{
//改变Controllor的Model的值,VIEW的UI控件的值会跟着变
Controllor.Model.ID = "2";
Controllor.Model.Name = "jacky";
Controllor.UpdatePerson();
}
private void PersonForm_Load(object sender, EventArgs e)
{
}
}
}
最后是程序启动:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApplication10
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Controllor-First模式,先创建Controllor(PersonControllor)再将View(PersonForm)注入到Controllor(PersonControllor)中
PersonControllor controllor = new PersonControllor(new PersonForm());
Application.Run(controllor.View);
}
}
}