Windows Forms(二)
导读
1、用VS创建一个Windows Forms程序
2、分析上面的程序
3、Mediator pattern(中介者模式)
4、卡UI怎么办——BackgroundWorker组件
用VS创建一个Windows Forms程序
博主应为项目需要用的VS2005,所以这个系列的Windows Forms 特指Windows Forms 2.0。
打开VS2005 –> 建立 Windows应用程序,过程截图如下(其实这种简单的步骤,做C#开发都会)
拖拽一个Button 和 TextBox 控件,界面如下
双击Button控件添加Click事件,代码如下:
private void button1_Click(object sender, EventArgs e)
{
this.textBox1.Text = "Windows Forms (二) By Aphasia";
}
运行效果为:
分析上面的程序
我们关注红框中的.cs 文件,这是C#源代码文件,至于.resx那是资源文件,我们现在不需要关注。上面有3个.cs 文件(3个C#源代码)。我们先看 Program.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms; namespace WinFormDemo
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
默认引用了3个命名控件(这个可以通过修改VS的模板来修改默认引用的命名空间) 继续往下看
静态类 Program 下有一个Main方法,Main方法上有一个 STAThread 的特性(Attribute)(含义是单线程模型,这个我们暂时不需要关心,我们以后会谈到,这里我们只需要了解就可以了)。Main方法里有3行代码,这3行代码在前一篇Windows Forms的博客中提到过
Application.EnableVisualStyles(); 开启WinXp的样式
Application.SetCompatibleTextRenderingDefault(false); 设置文本的现实方式(是GDI+还是GDI,这个我们以后将System.Drawing时会提到,这里暂时了解即可)
Application.Run(new Form1()); 在当前AppDomain中加载 Form1窗体
再看 Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms; namespace WinFormDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
this.textBox1.Text = "Windows Forms (二) By Aphasia";
}
}
}
默认命名控件跳过
看到 窗体类 Form1 前面有个关键字 partial,这个关键字的含义是分布类是.NET 2.0 引入的一个语法糖,含义是将一个类的定义分布在多个源码文件(.cs 中),好处嘛就是扩展性加强有利于前后台分离,继续往下看构造器
构造器中调用了 InitializeComponent 方法(中文含义是初始化组件),奇怪的是这个方法的定义没在Form1.cs 中尼,那它在哪尼?别急继续往下看
私有方法 button1_Click 参数类型有点像前一篇谈到 System.EventHandler 委托的原型定义
我们再看 Form1.Designer.cs
namespace WinFormDemo
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region Windows 窗体设计器生成的代码 /// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(, );
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(, );
this.button1.TabIndex = ;
this.button1.Text = "Click Me";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(, );
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(, );
this.textBox1.TabIndex = ;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(, );
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.MaximizeBox = false;
this.Name = "Form1";
this.Text = "用VS建第一个WinForm程序";
this.ResumeLayout(false);
this.PerformLayout(); } #endregion private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
}
}
乖乖,这个编译器生成的代码真多 。我们看到这个类也是一个分布类,这里定义了InitializeComponent 方法,所以在Forms.cs 中就直接可以调用了。我们看下InitializeComponent 的内容
Button控件和TextBox控件的初始化及赋值 注意 SuspendLayout 、ResumeLayout及PerformLayout这个两个方法的含义是挂了控件的布局逻辑与恢复布局逻辑,有点类似SQL中事务的逻辑 Begin tran … 各种增删改查 … commit tran的逻辑
Button 和 TextBox 是控件类,这里做私有字段
还有一个东西需要提下
private System.ComponentModel.IContainer components = null;
components 这是干嘛的?其实把这货删掉了我们的这个Demo也能跑起来(把Dispose 方法中对这货的引用注释掉)那编译器干嘛还有生成这货尼。原因是这样的,当我们引用一些设计时可见,运行时不可见的组件时,这货就有用了,在Dispose方法中释放一些非托管资源,对于初学Windows Form的朋友现在只需要了解即可,再后续的博文会详谈的。
对比我在前一篇写的程序,我把窗体绘制逻辑和AppDomain运行分离到两个类中,VS比我更进了一步,它将窗体绘制逻辑用分布类这个机制再分成两个源代码文件 ——一个设计时由VS生成的Form1.Designer.cs,以后后台类 Form1.cs。这是一种进步
Mediator pattern(中介者模式)
上面的Demo程序代码分析差不多了,我们来看一个设计模式 Mediator pattern(中介者模式)
我们先看 Wiki上定义
In Software Engineering, the mediator pattern defines an object that encapsulates how a set of objects interact. It promotes loose coupling by keeping objects from referring to each other explicitly, and it allows their interaction to be varied independently.Client classes can use the mediator to send messages to other clients, and can receive messages from other clients via an event on the mediator class.
白话一下:中介者模式定义了一个中介者类来封装各个对象的交互,这个模式保证了各个对象之间交互的松耦合(因为他们之间的交互是通过中介,各个对象之间也许都不知道各个对象的存在,好比你去通过中介租房的流程一样,你只知道有个中介,不一定知道房东是谁。下面我就以租房的例子来写一个Demo)
我们分析下需要写那些东西(由于这个笔记本没有装UML建模软件,现在没法画UML图,各位看客先凑合着看,后面补上)
一个中介类
一个房东和房客的基类
上面的两个都是抽象类
具体的中介类1
具体的房东类1
具体的房客类1
直接上代码
BaseZhongjie.cs
namespace WinFormDemo
{
public abstract class ZhongJie
{
public abstract void SendMsg(BasePerson person,string msg);
}
}
BasePerson.cs
namespace WinFormDemo
{
public abstract class BasePerson
{
// 房东与房客的共同点就是他们都知道中介,也就是他们应该有中介这个字段
protected ZhongJie zhongJie;
public BasePerson(ZhongJie zhongJie)
{
this.zhongJie = zhongJie;
}
}
}
FangDong.cs
namespace WinFormDemo
{
public class FangDong : BasePerson
{
public FangDong(ZhongJie zhongjie) : base(zhongjie)
{} // 向中介发布房源信息
public void Send(string msg)
{
base.zhongJie.SendMsg(this,msg);
} // 房东收到中介给予的消息
public void Notify(string msg)
{
System.Console.WriteLine("房东收到消息 {0} ",msg);
}
}
}
FangKe.cs
namespace WinFormDemo
{
public class FangKe : BasePerson
{
public FangKe(ZhongJie zhongjie) : base(zhongjie)
{} // 向中介发布求租信息
public void Send(string msg)
{
zhongJie.SendMsg(this,msg);
} // 房客收到中介给予的消息
public void Notify(string msg)
{
System.Console.WriteLine("房客收到消息 {0} ",msg);
}
}
}
ZhongJieA.cs
namespace WinFormDemo
{
public class ZhongJieA : ZhongJie
{
// 中介这注册了多个房东和房客信息
private FangDong fangDongA;
private FangKe fangKeA; public FangDong FangDongA
{
get{return fangDongA;}
set{fangDongA = value;}
}
public FangKe FangKeA
{
get{return fangKeA;}
set{fangKeA = value;}
} public override void SendMsg(BasePerson person,string msg)
{
#region 中介转发消息
if(person is FangDong)
{
if(fangKeA != null)
{
// 有房客在求租,中介给房客发送可以看房的信息
fangKeA.Notify("房东有房要出租,你可以去看房了。。。");
}
}
if(person is FangKe)
{
if(fangDongA != null)
{
fangDongA.Notify("有个小伙子想租你的房子,你看你什么时候有空我带他去看房");
}
}
#endregion
}
}
}
build.bat
csc /out:BaseLib.dll /t:library BasePerson.cs BaseZhongjie.cs
csc /out:Lib.dll /r:BaseLib.dll /t:library FangDong.cs FangKe.cs ZhongJieA.cs
csc /r:BaseLib.dll,Lib.dll App.cs
运行效果
源码下载
中介者模式讲完了,中介者模式和Windows Forms 有什么关系尼?其实Windows Forms 就用到了中介者模式, Form 窗体是中介者,各个控件如Button和TextBox就是上面的房东或房客,他们彼此不一定知道对方的存在,但是知道有窗体存在
Button 捕获了鼠标单击,委托给窗体(中介者)里的方法button1_Click执行,这个方法里通知 TextBox显示我们需要显示的内容。
从上面了流程来看Button根本就不需要知道有TextBox的存在,它只是委托出去单击的执行。
卡UI怎么办——BackgroundWorker组件
文章最后的给出一个 BackgroundWorker 的例子
我们用Thread.Sleep 模式后台卡UI,用进度条反应卡UI的操作完成了百分之多少
先看下效果
代码下载
本文完
Windows Forms(二)的更多相关文章
- .net chart(图表)控件的使用-System.Windows.Forms.DataVisualization.dll
这个案例指在介绍微软这套免费又功能强大的图表控件Microsoft Chart Controls for Microsoft .NET Framework 3.5,通过它,可让您的项目及报表,轻松套用 ...
- System.Windows.Forms.Timer
一.主要属性.方法和事件 Windows 窗体 Timer 是定期引发事件的组件.该组件是为 Windows 窗体环境设计的. 时间间隔的长度由 Interval 属性定义,其值以毫秒为单位.若启用了 ...
- C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常,不存在从对象类型System.Windows.Forms.DateTimePicker到已知的托管提供程序本机类型的映射。
一:C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常 其实,这个问题与C#的垃圾回收有关.垃圾回收器管 理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的 垃圾回收器 ...
- 从零开始学Xamarin.Forms(二) 环境搭建、创建项目
原文:从零开始学Xamarin.Forms(二) 环境搭建.创建项目 一.环境搭建 Windows下环境搭建: 1.下载并安装jdk.Android SDK和NDK,当然还需要 VS2013 ...
- Oracle 远程访问配置 在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标 C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素” C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作
Oracle 远程访问配置 服务端配置 如果不想自己写,可以通过 Net Manager 来配置. 以下配置文件中的 localhost 改为 ip 地址,否则,远程不能访问. 1.网络监听配置 ...
- Wizard Framework:一个自己开发的基于Windows Forms的向导开发框架
最近因项目需要,我自己设计开发了一个基于Windows Forms的向导开发框架,目前我已经将其开源,并发布了一个NuGet安装包.比较囧的一件事是,当我发布了NuGet安装包以后,发现原来已经有一个 ...
- windows forms 上一个类似于wpf snoop 的工具: Hawkeye
windows forms 上一个类似于wpf snoop 的工具: Hawkeye 周银辉 WPF上有snoop这样的run time object editor让人用着很爽, 今天搜到了一个for ...
- WPF中实例化Com组件,调用组件的方法时报System.Windows.Forms.AxHost+InvalidActiveXStateException的异常
WPF中实例化Com组件,调用组件的方法时报System.Windows.Forms.AxHost+InvalidActiveXStateException的异常 在wpf中封装Com组件时,调用组件 ...
- DotNetBar for Windows Forms 12.9.0.0_冰河之刃重打包版及制作Visual Studio C#项目模板文件详解
关于 DotNetBar for Windows Forms 12.9.0.0_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...
随机推荐
- 转载Expression Tree揭秘
概述 在.NET Framework 3.5中提供了LINQ 支持后,LINQ就以其强大而优雅的编程方式赢得了开发人员的喜爱,而各种LINQ Provider更是满天飞,如LINQ to NHiber ...
- 关于继承MonoBehaviour的一些记录
在开发游戏中,为了减少不必要的代码量,我们经常会继承MonoBehaviour,那么MonoBehaviour内部的内置方法Start.Update等等如果在父类中定义了,在子类中再次定义会发生什么事 ...
- ObjC语法练习 冒泡排序、选择排序、矩阵相乘
用OC实现的冒泡排序.选择排序.矩阵相乘,纯粹是用来练习语法. 冒泡排序,程序如下: void bubbleSort() { //初始化数组 NSMutableArray *array1 = [[NS ...
- ssh免密码登录记录
做mha.hadoop安装过程中都要用ssh免密码登陆,查过一些资料,踩过很多坑,下面用简单记录一下 首先要安装ssh linux : centOS 6.5 yum -y install *ssh* ...
- Win8.1激活
激活查询:在桌面状态下输入“Win+R”,进入运行栏目,输入slmgr.vbs -dlv 显示:最为详尽的激活信息,包括:激活ID.安装ID.激活截止日期 http://www.nruan.com/w ...
- (DP6.1.2.1)UVA 147 Dollars(子集和问题)
/* * UVA_147.cpp * * Created on: 2013年10月12日 * Author: Administrator */ #include <iostream> #i ...
- 理解class.forName()
使用jdbc方式连接数据库时会使用一句代码Class.forName(String className).这句话是什么意思呢?首先说一点Class.forName(String className)这 ...
- android132 360 05 手机定位
.网络定位:根据ip地址定位,根据ip地址在实际地址数据库中查询实际地址. 缺点:动态ip导致地址不准确. .基站定位:3个基站就可以确定实际位置,定位范围是几百米到几公里不等. .GPS定位:美国卫 ...
- 面试题总结之Linux/Shell
Linux Linux cshrc文件作用 Linux如何起进程/查看进程/杀进程 Linux 文件755 代表什么权限 Linux辅助线程 Linux进程间通信方法 pipeline,msgq... ...
- Middleware
Middleware The middleware gives a single shot to the views associated into Controllers, before execu ...