导读

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. C++学习笔记(九):作用域和命名空间

    作用域 作用域规则告诉我们一个变量的有效范围,它在哪儿创建,在哪儿销毁(也就是说超出了作用域).变量的有效作用域从它的定义点开始,到和定义变量之前最邻近的开括号配对的第一个闭括号.也就是说,作用域由变 ...

  2. 剑指OFFER之第一个只出现一次的字符(九度OJ1283)

    题目描述: 在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符. 输入: 输入有多组数据每一组输入一个字符串. 输出: 输出第一个只出现一次的字 ...

  3. 详解struts.multipart.saveDir的临时文件路径

    Struts2中的struts.multipart.saveDir主要是用来设置上传文件的临时目录,在不同的配置方式下,它的临时文件目录大有不同,好多人在设置后往往找不到这个临时目录在哪里,下面我就来 ...

  4. ASP.NET 学习的总结

    应用程序域 使用.Net建立的可执行程序*.exe,并没有直接承载到进程当中,而是承载到应用程序域(AppDomain)当中.应用程序域是.Net引入的一个新概念,它比进程所占用的资源要少,可以被看做 ...

  5. go strings 常用的几个函数

    fmt.Println(strings.ToUpper("hello world")) //转换为大写    fmt.Println(strings.ToLower("H ...

  6. 计算机思维or人的思维

    计算机领域就会有计算机领域的一些特性和一些思维方式,或者说有他自己的一些问题,须要用相应的思维方式来进行理解它,从而更好的驾驭他.有些时候遇到的一些问题,自己想却想不明确,也是由于我们没有把自己当做一 ...

  7. iOS 10 升级后无法真机测试 Could not find Developer Disk Image

    ---2016年9月20日更新 iOS 升级到10之后,你会发现无法进行真机测试了.这种情况我在iOS 8.4 .9.3更新的时候也遇到过.原因是Xcode 的DeviceSupport里面缺少了iO ...

  8. open_table与opened_table --2

    好多人在调优Mysql的时候,总是对open_tables和opend_tables两个参数分别不清. 网上好多解释都是这样的:open_tables:当前打开表的数量opened_tables:当前 ...

  9. 用java开发的网站或者程序

    中国移动的官网即其相关业务系统 阿里巴巴.淘宝网 58同城是java做的后台 铁道部12306 腾讯的拍拍网等 各大银行的交互应用系统,比如有的信用卡网银 另外,Android手机的大部分应用,其他智 ...

  10. 如何在 iOS 中解决循环引用的问题

    稍有常识的人都知道在 iOS 开发时,我们经常会遇到循环引用的问题,比如两个强指针相互引用,但是这种简单的情况作为稍有经验的开发者都会轻松地查找出来. 但是遇到下面这样的情况,如果只看其实现代码,也很 ...