C#事件作用和用法

Advertisement

例如有下面的需求需要实现:程序主画面中弹出一个子窗口。此时主画面仍然可以接收用户的操作(子窗口是非模态的)。子窗口上进行某些操作,根据操作的结果要在主画面上显示不同的数据。

即如下图所示:C#事件作用和用法
C#事件作用和用法
C#事件作用和用法

大多数我们会这样做:

表单1窗口定义:

C#事件作用和用法
C#事件作用和用法

 1  public partial class Form1 : Form
 2     {
 3
 4         public string LabelName
 5         {
 6             get { return this.label1.Text; }
 7             set { this.label1.Text = value; }
 8         }
 9
10         public Form1()
11         {
12             InitializeComponent();
13             this.button1.Click += new EventHandler(button1_Click);
14         }
15
16         /// <summary>
17         /// 按钮触发
18         /// </summary>
19         /// <param name="sender"></param>
20         /// <param name="e"></param>
21         private void button1_Click(object sender, EventArgs e)
22         {
23             Form2 form2 = new Form2();
24             form2.form1 = this;
25             form2.Show();
26         }
27     }

View Code

表单2窗口定义:

C#事件作用和用法
C#事件作用和用法

 1     public partial class Form2 : Form
 2     {
 3         public Form1 form1;
 4         public Form2()
 5         {
 6             InitializeComponent();
 7             this.button1.Click += new EventHandler(button1_Click);
 8         }
 9
10         /// <summary>
11         /// 表单2按钮触发
12         /// </summary>
13         /// <param name="sender"></param>
14         /// <param name="e"></param>
15         private void button1_Click(object sender, EventArgs e)
16         {
17             form1.LabelName = "改变之后";
18         }
19     }

View Code

这样虽然可以达到目的,但是各个模块之间产生了很强的耦合。一般说来模块之间的调用应该是单方向的:模块A调用了模块B,模块B就不应该反向调用A,否则就破坏了程序的层次,加强了耦合程度,也使得功能的改变和追加变得很困难。

所以这里就用到了事件:

下边是表单2中的事件定义:

 1  public partial class Form2 : Form
 2     {
 3         public delegate void OutputMessage(object sender, System.EventArgs e);
 4         public event OutputMessage ButtonClick;
 5
 6         public Form2()
 7         {
 8             InitializeComponent();

 9             this.button1.Click += new EventHandler(button1_Click);
10         }
11
12         /// <summary>
13         /// 表单2按钮触发
14         /// </summary>
15         /// <param name="sender"></param>
16         /// <param name="e"></param>
17         private void button1_Click(object sender, EventArgs e)
18         {
19             ButtonClick(this, e);
20         }
21     }

然后在表单1中进行捕获:

 1 public partial class Form1 : Form
 2     {
 3         public Form1()
 4         {
 5             InitializeComponent();
 6             this.button1.Click += new EventHandler(button1_Click);
 7         }
 8
 9         /// <summary>
10         /// 按钮触发
11         /// </summary>
12         /// <param name="sender"></param>
13         /// <param name="e"></param>
14         private void button1_Click(object sender, EventArgs e)
15         {
16             Form2 form = new Form2();
17             form.Show();
18             form.ButtonClick += new Form2.OutputMessage(form_ClickButton);
19         }
20
21         private void form_ClickButton(object sender, EventArgs e)
22         {
23             this.label1.Text = "改变之后";
24         }
25     }

这样,各个模块专心的做自己的事情,不需要过问其他模块的事情。

不知道说的对不对,还请指教。。。

原文:http://www.cnblogs.com/cn-blogs/p/3413652.html

Similar Posts:

  • 事件的基本用法

    事件的基本用法 事件的基本用法 我在对RO例子 Variants 跟踪时有了个意外收获,有种茅塞顿开. 提起事件,我也用过,一般都是控件上提供啥事件我就用啥了. 用的最多的就是OnClick事件,至于为啥这样用,我不知道, 稀里湖途地我用了快小半辈子了. 我从下面的代码开始跟踪的: procedure TVariantsClientMainForm.FormCreate(Sender: TObject); var i: integer; begin for i := 0 to Component

  • C/C++头文件的作用和用法

    示例代码编译运行环境:VS2012+Debug+Win32. 头文件是C/C++程序不可缺少的组成部分.使用头文件,应该注意头文件的作用和用法相关知识点. 1.头文件的作用 C/C++编译器采用的是分离编译模式.在一个项目中,有多个源文件存在,但是它们总会有一些内容是相同的,如使用相同的用户自定义类型.使用了相同的全局变量等.因此,将这些内容抽取出来放到头文件中,然后在提供给各个源文件包含,就可以避免这些内容的重复书写,提高编程效率和代码安全性. 所以,设立头文件的目的主要是:提供全局变量.全局

  • jquery事件preventDefault()方法用法实例

    本文实例讲述了jquery事件preventDefault()方法用法.分享给大家供大家参考.具体实现方法如下: 代码如下: <html> <head> <title>jquery事件:preventDefault()方法的使用</title> <script type="text/javascript" src="jquery-1.8.2.min.js"></script> <scrip

  • GetTickCount() 函数的作用和用法

    在要求误差不大于1毫秒的情况下,可以采用GetTickCount()函数,该函数的返回值是DWORD型,表示以毫秒为单位的计算机启动后经历的时间间隔.使用下面的编程语句,可以实现50毫秒的精确定时,其误差小于1毫秒. DWORD dwStart, dwStop; // 起始值和终止值 dwStop = GetTickCount(); while(TRUE) { dwStart = dwStop; // 上一次的终止值变成新的起始值 // 此处添加相应控制语句 do { dwStop = GetT

  • volatile的作用与用法(不允许编译器优化)

    先说说我的理解,volatile我们叫它"易变的",是一个类型修修饰符,一般情况下,我们定义了一个变量,如果说这个变量在整个代码中都没有改变,那么编译器就会把这个变量放到寄存器中,cpu取值就只在寄存器中取.但是在嵌入式中就会出现特殊情况了,很多时候,我们在代码中都不会改变一些变量的值(特别是寄存器的状态,或者某个引脚的状态),但是硬件很有可能去改变这个值,如按键改变某引脚的状态等一些情况,可是编译器并不知道这个变量已经发生改变,这个时候很有可能编译器所使用的值和实际值并不一致,所以C

  • HTML中&amp;lt;!DOCTYPE&amp;gt;作用及用法详解

    一.什么是DTD DTD(document type definition),文档类型定义.可定义合法的XML文档构建模块,它使用一系列合法的元素来定义文档的结构.通过DTD,每一个xml文件均可携带一个有关其自身格式的描述. 内部的DOCTYPE声明 eg:<!DOCTYPE 根元素 [元素声明]> [ 所以说,DOCTYPE是DTD的一个 在文档内的 声明形式.] 外部的DOCTYPE声明 假如DTD在原文件的外部,那么它应通过下面的语法被封装在一个DOCTYPE定义中. eg:<!

  • vb语法-unbind()函数作用及用法

    VB中UBound函数的功能及用法 返回一个 Long 型数据,其值为指定的数组维可用的最大下标. 语法 UBound(arrayname[, dimension]) UBound 函数的语法包含下面部分: 部分 描述 arrayname 必需的.数组变量的名称,遵循标准变量命名约定. dimension 可选的:Variant (Long).指定返回哪一维的上界.1 表示第一维,2 表示第二维,以此类推.如果省略dimension,就认为是 1. 说明 UBound 函数与 LBound 函数

  • .NET Attribute(特性)的作用与用法——几句话解决Attribute使用的困惑

    本小文旨在言简意赅的介绍.NET中Attribute(特性)的作用与使用,算是对Attribute学习的一个总结吧,不当之处烦请热心网友帮忙斧正,不胜感激!切入正题. 一点说明 只介绍作用与使用方法,不深究原理.[其原理可参考MSDN:http://msdn.microsoft.com/en-us/library/aa288454(v=vs.71).aspx 等相关文章] 什么是Attribute? Attribute不是别的东西,就是类(貌似废话).确切的说,它是为C#代码(类型.方法.属性等

  • tomcat antiResourceLocking antiJARLocking 的作用和用法

    我们先来看看这个 antiResourceLocking 到底是干什么的! If true, Tomcat will prevent any file locking. This will significantly impact startup time of applications, but allows full webapp hot deploy and undeploy on platforms or configurations where file locking can occ

  • 防火墙的作用及用法介绍

    在前面小编给大家在说明病毒.木马的时候,总是会给大家提到说要安装防火墙,可是防火墙是什么呢?防火墙的作用是什么呢?下面我们一起来看看小编给大家说说防火墙的相关知识.详细内容如下: 一.防火墙是什么?所谓防火墙指的是一个由软件和硬件设备组合而成.在内部网和外部网之间.专用网​与公共网之间的界面上构造的保护屏障.是一种获取安全性方法的形象说法,它是一种计算机硬件和软件的结合,使Internet与Intranet之间建立起一个安全网关(Security Gateway),从而保护内部网免受非法用户的侵