C#事件


1.2      事件

事件是C#语言内置的语法,可以定义和处理事件,为使用组件编程提供了良好的基础。

1.16.1       事件驱动

Windows操作系统把用户的动作都看作消息,C#中称作事件,例如用鼠标左键单击按钮,发出鼠标单击按钮事件。Windows操作系统负责统一管理所有的事件,把事件发送到各个运行程序。各个程序用事件处理函数响应事件,这种方法也叫事件驱动。

C#语言使用组件编制Windows应用程序。组件本质上是类。在组件类中,预先定义了该组件能够响应的事件,以及对应的事件函数(不是程序员编制的事件处理函数),该事件发生,将自动调用相应的预定义事件函数。例如,按钮类中定义了单击事件Click和单击事件函数。一个组件可能定义了多个事件,应用程序中不必也没必要响应所有的事件,而只需响应其中很少事件,程序员编制相应的事件处理函数,用来完成需要响应的事件所应完成的功能。现在的问题是,第一,如何把程序员编制的事件处理函数和组件类中预先定义的事件函数联系起来。第二,如何使不需响应的事件无动作。这是本节要解决的问题。

1.16.2       事件的声明

在C#中,事件首先代表事件本身,例如按钮类的单击事件,同时,事件还是代表类型引用变量,可以代表程序员编制的事件处理函数,把事件和事件处理函数联系在一起。下面的例子定义了一个Button组件,这个例子不完整,只是说明问题。实际在C#语言类库中已预定义了Button组件,这里的代码只是想说明Button组件中是如何定义事件的。例子如下:

public delegate void EventHandler(object sender,EventArgs e);//代表类型声明

//EventHandler变量可以代表没有返回值,参数为(object sender,EventArgs e)的函数

public class Button:Control//定义一个按钮类Button组件

{…//按钮类Button其它成员定义

public event EventHandler Click;//声明一个事件Click,是代表类型引用变量

protected void OnClick(EventArgs e)//Click事件发生,自动触发OnClick方法

{   if(Click!=null)//如果Click已代表了事件处理函数,执行这个函数

Click(this,e);

}

public void Reset()

{   Click=null;}

}

在这个例子中,Click事件发生,应有代码(未列出)保证自动触发OnClick方法。Click是类Button的一个事件,同时也是代表类型EventHandler的引用变量,如令Click代表程序员编制的事件处理函数,Click事件发生时,将执行程序员编制的事件处理函数,完成程序员希望完成的工作。如果Click为null,OnClick函数将不做任何事情。下节将介绍用何种语句使Click代表程序员编制的事件处理函数。

1.16.3       事件的预订和撤消

在随后的例子中,我们声明了一个使用Button类的登录对话框类,对话框类含有两个按钮:OK和Cancel按钮。

public class LoginDialog: Form//登录对话框类声明

{   Button OkButton;

Button CancelButton;

public LoginDialog()//构造函数

{   OkButton=new Button();//建立按钮对象OkButton

//下条语句令Click代表OkButtonClick方法,注意+=的使用

OkButton.Click+=new EventHandler(OkButtonClick);

CancelButton=new Button();//建立按钮对象CancelButton

CancelButton.Click += new EventHandler(CancelButtonClick);

}

void OkButtonClick(object sender, EventArgs e)//程序员编制的事件处理函数

{…//处理OkButton.Click事件的方法,完成程序员希望完成的工作

}

void CancelButtonClick(object sender, EventArgs e)

{…//处理CancelButton.Click事件的方法,完成程序员希望完成的工作

}

}

在例子中建立了Button类的两个实例,单击按钮事件Click通过如下语句和事件处理方法联系在一起:OkButton.Click+=new EventHandler(OkButtonClick),该语句的意义是使OkButton.Click代表事件处理方法OkButtonClick,这样只要Click事件被触发,事件处理方法OkButtonClick就会被自动调用。撤消事件和事件处理方法OkButtonClick的联系采用如下语句实现:OkButton.Click-=new EventHandler(OkButtonClick),这时,OkButton.Click就不再代表事件处理方法,Click事件被触发,方法OkButtonClick就不会被调用了。务必理解这两条语句的用法。使用Visual Studio.Net集成环境可以自动建立这种联系,在自动生成的代码中包括这两条语句。

1.3      索引指示器

在C#语言中,数组也是类,比如我们声明一个整型数组:int[] arr=new int[5],实际上生成了一个数组类对象,arr是这个对象的引用(地址),访问这个数组元素的方法是:arr[索引],在数组类中,使用索引访问元素是如何实现的呢?是否可以定义自己的类,用索引访问类中的数据成员?索引指示器(indexer)为我们提供了通过索引方式方便地访问类的数据成员的方法。

首先看下面的例子,用于打印出小组人员的名单:

using System

class Team

{   string[] s_name = new string[2];//定义字符串数组,记录小组人员姓名

public string this[int nIndex]//索引指示器声明,this为类Team类的对象

{   get//用对象名[索引]得到记录小组人员姓名时,调用get函数

{   return s_name[nIndex];

}

set//用对象名[索引]修改记录小组人员姓名时,调用set函数

{   s_name[nIndex] =value;//value为被修改值

}

}

}

class Test

{   public static void Main()

{   Team t1 = new Team();

t1[0]="张三";

t1[1]="李斯";

Console.WriteLine("{0},{1}",t1[0], t1[1]);

}

}

显示结果如下:张三,李斯

1.4      命名空间

一个应用程序可能包含许多不同的部分,除了自己编制的程序之外,还要使用操作系统或开发环境提供的函数库、类库或组件库,软件开发商处购买的函数库、类库或组件库,开发团队中其它人编制的程序等。为了组织这些程序代码,使应用程序可以方便地使用这些程序代码,C#语言提出了命名空间的概念。命名空间是函数、类或组件的容器,把它们按类别放入不同的命名空间中,命名空间提供了一个逻辑上的层次结构体系,使应用程序能方便的找到所需代码。这和C语言中的include语句的功能有些相似,但实现方法完全不同。

1.18.1       命名空间的声明

用关键字namespace声明一个命名空间,命名空间的声明要么是源文件using语句后的第一条语句,要么作为成员出现在其它命名空间的声明之中,也就是说,在一个命名空间内部还可以定义命名空间成员。全局命名空间应是源文件using语句后的第一条语句。在同一命名空间中,不允许出现同名命名空间成员或同名的类。在声明时不允许使用任何访问修饰符,命名空间隐式地使用public修饰符。例子如下:

using System;

namespace N1//N1为全局命名空间的名称,应是using语句后的第一条语句

{   namespace N2//命名空间N1的成员N2

{   class A//在N2命名空间定义的类不应重名

{   void f1(){};}

class B

{   void f2(){};}

}

}

也可以采用非嵌套的语法来实现以上命名空间:

namespace N1.N2//类A、B在命名空间N1.N2中

{   class A

{   void f1(){};}

class B

{   void f2(){};}

}

也可以采用如下格式:

namespace N1.N2//类A在命名空间N1.N2中

{   class A

{   void f1(){};}

}

namespace N1.N2//类B在命名空间N1.N2中

{   class B

{   void f2(){};}

}

1.18.2       命名空间使用

如在程序中,需引用其它命名空间的类或函数等,可以使用语句using,例如需使用上节定义的方法f1()和f2(),可以采用如下代码:

using N1.N2;

class WelcomeApp

{   A a=new A();

a.f1();

}

using N1.N2实际上是告诉应用程序到哪里可以找到类A。请读者重新看一下1.2.1节中的例子。

1.5      非安全代码

在C和C++的程序员看来,指针是最强有力的工具之一,同时又带来许多问题。因为指针指向的数据类型可能并不相同,比如你可以把int类型的指针指向一个float类型的变量,而这时程序并不会出错。如果你删除了一个不应该被删除的指针,比如Windows中指向主程序的指针,程序就有可能崩溃。因此滥用指针给程序带来不安全因素。正因为如此,在C#语言中取消了指针这个概念。虽然不使用指针可以完成绝大部分任务,但有时在程序中还不可避免的使用指针,例如调用Windows操作系统的API函数,其参数可能是指针,所以在C#中还允许使用指针,但必须声明这段程序是非安全(unsafe)的。可以指定一个方法是非安全的,例如:unsafe void F1(int * p){…}。可以指定一条语句是非安全的,例如:unsafe int* p2=p1;还可以指定一段代码是非安全的,例如:unsafe{ int* p2=p1;int* p3=p4;}。在编译时要采用如下格式:csc 要编译的C#源程序 /unsafe。

08C#事件的更多相关文章

  1. JNI详解---从不懂到理解

    转载:https://blog.csdn.net/hui12581/article/details/44832651 Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 C ...

  2. Jquery的点击事件,三句代码完成全选事件

    先来看一下Js和Jquery的点击事件 举两个简单的例子 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...

  3. 关于 Chrome 浏览器中 onresize 事件的 Bug

    我在写插件时用到了 onresize 事件,在反复地测试后发现该事件在 Chrome 及 Opera(内核基本与 Chrome 相同,以下统称 Chrome)浏览器打开时就会执行,这种情况也许不能算作 ...

  4. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  5. C++中的事件分发

    本文意在展现一个C++实现的通用事件分发系统,能够灵活的处理各种事件.对于事件处理函数的注册,希望既能注册到普通函数,注册到事件处理类,也能注册到任意类的成员函数.这样在游戏客户端的逻辑处理中,可以非 ...

  6. 移动端IOS点击事件失效解决方案

    解决方案 解决办法有 4 种可供选择: 1 将 click 事件直接绑定到目标元素(即 .target)上 2 将目标元素换成 <a> 或者 button 等可点击的元素 3 将 clic ...

  7. Android笔记——Button点击事件几种写法

    Button点击事件:大概可以分为以下几种: 匿名内部类 定义内部类,实现OnClickListener接口 定义的构造方法 用Activity实现OnClickListener接口 指定Button ...

  8. HTML 事件(一) 事件的介绍

    本篇主要介绍HTML中的事件知识:事件相关术语.DOM事件规范.事件对象. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三 ...

  9. HTML 事件(二) 事件的注册与注销

    本篇主要介绍HTML元素事件的注册.注销的方式. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流.事件委托 4. ...

随机推荐

  1. windows系统修改mysql端口的方法

    1.首先在控制面板--管理工具--服务里停止mysql服务

  2. Masonry 动画更新约束

    前言 说到iOS自动布局,有很多的解决办法.有的人使用xib/storyboard自动布局,也有人使用frame来适配.对于前者,笔者并不喜欢,也不支持.对于后者,更是麻烦,到处计算高度.宽度等,千万 ...

  3. Django 缓存 使用 Redis Memcached 为网站提速

    RedisRedis是一种键值对类型的内存数据库,读写内存比读写硬盘快,我们在Django里面使用Redis非常方便,下面给出详细步骤 基于Ubuntu 1. 安装Redis和django-redis ...

  4. Linux设备模型 (2)

    上一篇文章<Linux设备模型 (1)>主要介绍了Linux设备模型在用户空间的接口sysfs,用户通过这个接口可以一览内核设备的全貌.本文将从Linux内核的角度来看一看这个设备模型是如 ...

  5. WebDriverWait显示等待

    等待页面加载完成,找到某个条件发生后再继续执行后续代码,如果超过设置时间检测不到则抛出异常 WebDriverWait(driver, timeout, poll_frequency=0.5, ign ...

  6. asp.net mvc 多字段排序

    以下代码可实现多字段排序,通过点击列标题,实现排序. 控制器: public ActionResult Index(string sortOrder) { ViewBag.FirstNameSortP ...

  7. vue中使用element写点击input内部标签(使用模态框传值)

    首先附上源码地址 https://files.cnblogs.com/files/maruihua/vue-tagsinput-master.zip 这个是我修改后的代码.取消了部分功能,添加的一些功 ...

  8. python网络爬虫之三re正则表达式模块

    """ re正则表达式,正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的 一些特定字符,及这些特定字符的组合,组成一个"规则字符串",然后用 ...

  9. python中字典的陷阱

    把字典与列表组合,如 i=20 s=[]#定义一个空列表 b={'d':i}#定义一个字典 while i>0: i=i-1 b['d']=i#更新字典的值 s.append(b) print( ...

  10. Poj 2947 widget factory (高斯消元解同模方程)

    题目连接: http://poj.org/problem?id=2947 题目大意: 有n种类型的零件,m个工人,每个零件的加工时间是[3,9],每个工人在一个特定的时间段内可以生产k个零件(可以相同 ...