C#教材_委托与事件ppt课件.ppt_第1页
C#教材_委托与事件ppt课件.ppt_第2页
C#教材_委托与事件ppt课件.ppt_第3页
C#教材_委托与事件ppt课件.ppt_第4页
C#教材_委托与事件ppt课件.ppt_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第八章 委托与事件,目标,实现委托 定义和引发事件,概述,委托和事件在.NET framework中的应用非常广泛。然而,较好地理解委托和事件对很多刚刚接触C#的学员来说并不容易。它们就像一道坎儿,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里迷糊,浑身不自在。,了解委托,public class ClassPeople public void SayChinese(string name) Console.WriteLine(你好, + name); public void DoWork(string name) SayChinese(name);/传字符串参数 class P

2、rogram static void Main(string args) ClassPeople cp = new ClassPeople(); cp.DoWork(“张三); System.Console.ReadLine(); ,我们日常中问候例子中国人之间,了解委托,与美国问候: public class ClassPeople public void SayChinese(string name) Console.WriteLine(你好, + name); public void SayEnglish(string name) Console.WriteLine(Hello, + n

3、ame); public enum Language English, Chinese ,public void DoWork(string name, Language lang) switch (lang) case Language.English: SayEnglish(name); break; case Language.Chinese: SayChinese(name); break; ,了解委托,class Program static void Main(string args) ClassPeople cp = new ClassPeople(); cp.DoWork(“张

4、三, ClassPeople.Language.Chinese); cp.DoWork(“zhangsan, ClassPeople.Language.English); System.Console.ReadLine(); 我们细想一下,这个方法的扩展性也太差了一点吧。如果我们以后我们需要再添加韩文版、日文版等等,我们就不得不反复修改枚举和Ddwork()方法,以适应新的需求。那么我们有没有更好的解决方案?,了解委托,引入委托: public delegate void SayDelegate(string name); public class ClassPeople public voi

5、d SayChinese(string name) Console.WriteLine(你好, + name); public void SayEnglish(string name) Console.WriteLine(Hello, + name); /注意此方法,它接受一个SayDelegate类型的方法作为参数 public void DoWork(string name, SayDelegate MakeSay) MakeSay(name); ,了解委托,class Program static void Main(string args) ClassPeople cp = new C

6、lassPeople(); cp.DoWork(“张三, cp.SayChinese); cp.DoWork(“zhangsan, cp.SayEnglish); System.Console.ReadLine(); 委托是一种特殊的对象类型。它定义了方法的类型,使得可以将方法当做另一个方法的参数来进行传递,其特殊之处在于,我们以前定义的所有对象都包含数据,而委托包含的只是方法的地址。这种将方法动态地赋给参数的做法,可以避免在程序中大量使用if else、swith语句,同时使得程序具有更好的扩展性。,了解事件,在说明事件的原理之前,我们先来做一个例子,如下: 1、启动VS,建立一个winfo

7、rm应用程序,在form窗口中,我们建立一个按钮,当点击这个按钮时,弹出消息you clicked me!。 2、关于winform我们在以后会详细讲解。 3、我们双击按钮后,在button1的click事件中的代码如下: private void button1_Click(object sender, EventArgs e) MessageBox.Show(you clicked me!); 这是一个完整的私有方法,参数为object sender和EventArgs e。,Object sender与 EventArgs e,(1)第一个参数sender是object基类,它表示了bu

8、tton1类本身,可以经过显式转换为button1类. (Button)sender (2)EventArgs是包含事件数据的类的基类,用于传递事件的细节,EventArgs是所有其它事件类的基类。,我们怎么把这个方法和事件联系起来?,(1)我们通过程序界面看到,代码如下: this.button1.Click += new System.EventHandler(this.button1_Click); (2)this表示类本身(即form)而button1是它的一个控件,Click 是button预定义的一个标准事件 (3)通过 += 将 一个System.EventHandler(thi

9、s.button1_Click)的方法赋给了click事件。,System.EventHandler是什么?,(1)System.EventHandler 就是一个系统预定义的委托。 (2)该委托将事件与事件处理程序连接。 (3)委托是一个定义签名的类型,即定义了一个方法的返回值类型和参数列表类型。 (4)系统的委托声明如下 public delegate void EventHandler( object sender , EventArgs e ) 它定义了一个函数(方法)签名的方式。 (5)private void button1_Click(object sender, EventAr

10、gs e) 满足此签名方式: 一、没有返回值 二、传入参数,委托,(1)委托是一个类. (2)它包含对方法的引用 (3)帮助决定在运行时调用哪个方法 (4)步骤 定义委托 实例化委托 使用委托 (5)如刚刚的new System.EventHandler(this.button1_Click);,自定义委托,(1)public delegate void DelegateName(); (2)委托可以有返回值,如: public delegate int CallFun(int a,int b);,实例化委托的过程,/定义委托 public delegate int CallFun(int a

11、, int b); class MathsOperations public int MulFun(int a, int b) return a * b; public int DivFun(int a, int b) return a / b; ,/实例化委托1(乘法) CallFun DelegateObj1=new CallFun(MathsOprations.MulFun); /实例化委托2(除法) CallFun DelegateObj2 = new CallFun(MathsOprations.DivFun);,使用委托,/定义委托 public delegate int Call

12、Fun(int a, int b); class MathsOperations public int MulFun(int a, int b) return a * b; public int DivFun(int a, int b) return a / b; ,/实例化委托1(乘法) CallFun DelegateObj1=new CallFun(MathsOprations.MulFun); /使用委托 Console.WriteLine(DelegateObj1(2, 4); /实例化委托2(除法) CallFun DelegateObj2 = new CallFun(MathsO

13、prations.DivFun); /使用委托 Console.WriteLine(DelegateObj2(4, 2); Console.ReadLine();,多播委托,一个委托中可有多个方法 Delegate string delegateTest(string s); delegateTest dt = new delegateTest(f1) delegateTest dt2 = new delegateTest(f3) dt = dt+dt2; dt += new delegateTest(f2),使用多播委托,/定义委托 public delegate void CallFun(

14、int a, int b); class MathsOprations public static int result; public static void MulFun(int i, int j) result = i * j; public static void DivFun(int i, int j) result = result *(i / j); ,/实例化委托 CallFun DelegateObj = new CallFun(MathsOprations.MulFun); /多播委托 DelegateObj += new CallFun(MathsOprations.Di

15、vFun); /调用多播委托 DelegateObj(9, 3); System.Console.WriteLine(结果是:0, MathsOprations.result); Console.ReadLine();,多播委托是什么?,多播委托可绑定多个方法,匿名方法,在委托中直接写代码,而不是调用方法。如下:,class Program delegate string delegateTest(string val); static void Main(string args) string mid = ,middle part,; delegateTest anonDel = deleg

16、ate(string param) param += mid; param += and this was added to the string.; return param; ; Console.WriteLine(anonDel(Start of string); Console.ReadLine(); ,委托总结,传统委托的定义如下: delegate 返回值 委托名称(参数),public delegate void aa(int a); public class bb public static void cc(int a) Console.WriteLine(a); ,/我们可以

17、直接使用方法输出 bb.cc(1); /也可以使用委托输出 aa NewAa=new aa(bb.cc); NewAa(1); /匿名使用 aa NewAa2 = delegate(int a) Console.WriteLine(a); ; NewAa2(1);,泛型委托,泛型委托的定义如下: delegate 返回值 委托名称(T 参数名),public delegate void aa(T a); public class bb public static void cc(int a) Console.WriteLine(a); ,/使用泛型委托 aa NewAa = new aa(bb

18、.cc); NewAa(1); /匿名使用 aa NewAa2 = delegate(int a) Console.WriteLine(a); ; NewAa2(1);,Lambda表达式替换了匿名方法 delegate double Cal(double a, double b); 采用Lambda表达式调用 Cal aaa = (aa1, bb1) = aa1 + bb1; /=左边是参数,右边是实现方式 Console.WriteLine(aaa(2, 3);,C#3.0新功能(Lambda表达式),用Lambda表达式实现匿名委托,public delegate void aa(T a

19、); public class bb public static void cc(int a) Console.WriteLine(a); ,aa NewAa2 = a= Console.WriteLine(a); ; NewAa2(1);,回到事件,(1)事件处理的工作流程是系统有一个在后台专门监听事件的对象,他会不停捕捉用户的操作,当用户按下鼠标时,立刻被捕捉。 (2)如果捕捉到,就调用对此操作的定义的方法也就是(button1_Click方法)。 (3)注意委托的参数,与button1_Click方法中的参数一致。满足参数一样的,我们就说符合签名,可以调用。 (4)系统预定义了许多事件,

20、其中Click事件是系统为button1定义好的事件,系统定义如下:public event EventHandler Click;这在我们生成的程序中是看不到的。,事件原理,1、定义一个委托(类似于方法指针),并定义签名方式(输入参数),并通过订阅的方式预定方法(满足签名条件的方法)。 2、通过监听对象捕获事件,通过预先定义的方法,产生相应的结果。,事件,使用C#中的事件,对象可以将关于事件或已发生变化的信息通知其他对象 把事件信息通知其他对象的对象称为发布方 注册到事件的对象称为订阅方 步骤 定义事件 给对象预订该事件 通知事件的订户,定义事件,发布方 定义委托 基于该委托定义事件,预订事

21、件,能否给对象预订事件取决于事件是否存在。如果事件存在,那么要给对象预订事件,只须添加一个当事件被引发时将调用方法的委托即可。,通知预定对象,(1)要通知所有已预订事件的对象,只需引发该事件 If(condition)eventMe(); (2)click事件是系统预定义的事件,一旦用户点击鼠标就会捕捉到。,自定义事件,我们可以通过自定义一个事件来进一步了解事件与委托的处理原理: 首先用一个死循环来模拟监听,我们把这个方法放入UserInputMonitor类中,当然这是一个公共类: public void Run() /finished永远是false,所以永远循环 bool finishe

22、d = false; do if (Console.ReadLine() = h) /在这里使用这个事件,格式就是委托的格式,事件发生人是本类,新实例化一个空事件类传递参数。 OnUserRequest(this, new EventArgs(); while (!finished); ,自定义事件,(1) 定义一个委托,可以放在类外,也可以放在类内,好像一个方法指针,包含指定的事件发生对象和描述事件本身的事件对象 public delegate void UserRequest(object sender, EventArgs e); 我们把它放在类外. (2)自定义一个事件,不是系统本身的

23、,如click!,要放在类内,而且必须指定委托 public event UserRequest OnUserRequest; 此代码不断的要求用户输入字符,如果输入的结果是h,则触发OnUserRequest事件,事件的触发者是本身(this),事件细节无(没有传递任何参数的EventArgs实例)。我们给这个类取名为UserInputMonitor。,自定义事件,我们还要定义一个Client类,在类中定义一个方法。 private void ShowMessage(object sender,EventArgs e) Console.WriteLine(HaHa!); 最后要做的是把这个方

24、法和事件联系起来(订阅事件),我们把它写到Client类的构造函数里。 public Client(UserInputMonitor m) m.OnUserRequest+=new UserRequest(this.ShowMessage); ,自定义事件,好了,我们下面来运行它了, (1)首先得实例化UserInputMonitor类 UserInputMonitor monitor=new UserInputMonitor(); (2)下面创建客户端的实例。 Client aa = new Client(monitor); (3)最后让monitor开始监听事件。 monitor.run(); 完整的代码在备注中,进一步研究,在上一个例子中我们在委托中使用了EverntArgs类 , EventArgs 是包含事件数据的类的基类。 public delegate void UserRequest(object sender, EventArgs e); 我们发现如果编写一个接受键盘输入的事件时,我们采用了KeyPressEventArgs,如: private void textBox1_KeyPress(obj

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论