导读

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控件的初始化及赋值 注意 SuspendLayoutResumeLayoutPerformLayout这个两个方法的含义是挂了控件的布局逻辑与恢复布局逻辑,有点类似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(二)的更多相关文章

  1. .net chart(图表)控件的使用-System.Windows.Forms.DataVisualization.dll

    这个案例指在介绍微软这套免费又功能强大的图表控件Microsoft Chart Controls for Microsoft .NET Framework 3.5,通过它,可让您的项目及报表,轻松套用 ...

  2. System.Windows.Forms.Timer

    一.主要属性.方法和事件 Windows 窗体 Timer 是定期引发事件的组件.该组件是为 Windows 窗体环境设计的. 时间间隔的长度由 Interval 属性定义,其值以毫秒为单位.若启用了 ...

  3. C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常,不存在从对象类型System.Windows.Forms.DateTimePicker到已知的托管提供程序本机类型的映射。

    一:C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常 其实,这个问题与C#的垃圾回收有关.垃圾回收器管 理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的 垃圾回收器 ...

  4. 从零开始学Xamarin.Forms(二) 环境搭建、创建项目

    原文:从零开始学Xamarin.Forms(二) 环境搭建.创建项目 一.环境搭建 Windows下环境搭建:     1.下载并安装jdk.Android SDK和NDK,当然还需要 VS2013 ...

  5. 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.网络监听配置 ...

  6. Wizard Framework:一个自己开发的基于Windows Forms的向导开发框架

    最近因项目需要,我自己设计开发了一个基于Windows Forms的向导开发框架,目前我已经将其开源,并发布了一个NuGet安装包.比较囧的一件事是,当我发布了NuGet安装包以后,发现原来已经有一个 ...

  7. windows forms 上一个类似于wpf snoop 的工具: Hawkeye

    windows forms 上一个类似于wpf snoop 的工具: Hawkeye 周银辉 WPF上有snoop这样的run time object editor让人用着很爽, 今天搜到了一个for ...

  8. WPF中实例化Com组件,调用组件的方法时报System.Windows.Forms.AxHost+InvalidActiveXStateException的异常

    WPF中实例化Com组件,调用组件的方法时报System.Windows.Forms.AxHost+InvalidActiveXStateException的异常 在wpf中封装Com组件时,调用组件 ...

  9. DotNetBar for Windows Forms 12.9.0.0_冰河之刃重打包版及制作Visual Studio C#项目模板文件详解

    关于 DotNetBar for Windows Forms 12.9.0.0_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...

随机推荐

  1. Java 判断是否为汉字 判断是否为乱码 判断字符串是否为双整型数字 整数 数字

    /**  * 判断是否为汉字  *   * @param str  * @return  */ public static boolean isGBK(String str) {  char[] ch ...

  2. 理解shared_ptr<T>

    1.shared_ptr<T>解决什么问题? auto_ptr有个局限,拥有权转移.这往往不符合我们的需求,有时候我们期望,多个资源管理对象可以共享一个资源,当引用计数为0的时候,执行de ...

  3. C#-datagridview隐藏行头

    在进行datagridview的设置的过程中,常常会遇到需要设定datagridview1的行头显示,这就需要用到datagridview的属性: RowHeadersVisible属性设置为fals ...

  4. Aizu 2305 Beautiful Currency DP

    Beautiful Currency Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest ...

  5. Android中由IP地址查询经纬度坐标的实例

    大家都知道,根据IP地址就可以知道它所在的具体位置,在Android中同样可以由IP地址得到它的位置,即具体的地理经纬度坐标. 本文就直接以代码的方式演示如何根据IP地址查询地理经纬度坐标位置,下面的 ...

  6. [React Fundamentals] Accessing Child Properties

    When you're building your React components, you'll probably want to access child properties of the m ...

  7. Linux PAM&&PAM后门

    Linux PAM&&PAM后门 我是壮丁 · 2014/03/24 11:08 0x00 PAM简介 PAM (Pluggable Authentication Modules )是 ...

  8. [Effective C++ --027]尽量少做转型动作

    引言                                                                                                   ...

  9. [Effective C++ --006]若不能使用编译器自动生成的函数,就该明确拒绝

    ■本文内容■□第一节 <引言> 在条款五的讲解中,我们已经知道编译器是聪明的家伙,它会帮助你生成类的构造函数.析构函数.一个copy构造函数和一个赋值运算符.有时真的要感谢编译器所做的这一 ...

  10. 应聘.net开发工程师常见的面试题(五)

    1.描述一下C#中索引器的实现过程,是否只能根据数字进行索引? 答:不是.可以用任意类型. 2.在C#中,string str = null 与 string str = ” ” 请尽量使用文字或图象 ...