c#的委托delegate事件的详细使用

一、无参数,无返回的委托事件

委托事件类、事件的发生源。1.声明委托  2定义事件 3具体方法

 public class Test
{
// ….
public delegate void TestHandler();//无参数,无返回委托
public event TestHandler TestEvent;//事件
public void OnTestHandler()//调用
{
if(TestEvent != null) //不等于null 说明该事件已经注册有函数
{
this.TestEvent();
}
}
}

调用触发事件方法(这里把注册和调用写在一起,实际可以把注册写在另外的类)

 class Program
{
3 static void Main(string[] args)
4 {
Test model = new Test();//实列
6 model.TestEvent += model_TestEvent;//为model 注册TestEvent事件的执行方法
model.OnTestHandler();//调用引发事件
}
static void model_TestEvent()//事件执行方法,该方法样式要与委托一致(参数,返回值)
10 {
11 Console.WriteLine("这是最简单的事件");
}
}

执行效果

补充1、委托链。通过+= 添加执行函数。

 model.TestEvent += model_TestEvent;//为model 注册TestEvent事件的执行方法,符合TestHandler委托样式(参数,返回值)的方法都可以进行注册,可注册多个函数,按顺序执行。如改为
model.TestEvent += model_TestEvent1;
//model.TestEvent += new Test.TestHandler(model_TestEvent1);也可以这样写
model.TestEvent += model_TestEvent2;
static void model_TestEvent1()
{
Console.WriteLine("这是事件的函数1");
}//可设置断点看执行顺序
static void model_TestEvent2()
{
Console.WriteLine("这是事件的函数2");
}

执行效果

补充2、委托事件 结合在发布订阅者模式中。

Main(string[] args)方法中我们进行了注册和调用,像观察者模式使用,就会把注册和调用进行分开。

注册类,也就是所谓的订阅类。该类也可以写成接口,给不同业务的监听者用来继承扩张,这里所有监听者都执行model_TestEvent()函数。

 public class Listeners
{
//注册
public void registerEvent(Test model)
{
model.TestEvent += newTest.TestHandler(model_TestEvent);
}
//注销
public void nullifyEvent(Test model)
{
model.TestEvent -= newTest.TestHandler(model_TestEvent);
}
public virtual void model_TestEvent()
{
Console.WriteLine("这是所有监听者要执行的函数");
}
}

这里原来是注册事件,现在改为实例,注册监听者。。

 static void Main(string[] args)
{
Test model = new Test();
//可以实例注册多个监听者
Listeners listener1 = new Listeners();
Listeners listener2 = new Listeners();
listener1.registerEvent(model);
8 listener2.registerEvent(model); model.OnTestHandler(); //事件触发后,会向所有注册的监听者发送,所有监听者执行函数model_TestEvent
11 }

执行效果

二、带参数、返回值的委托事件

首先定义事件的参数,这是自定义事件传入的参数,从Eventargs继承,也可直接用Eventargs,这里为了简单就只给了个string字段,利用构造函数赋值。

一般带返回的委托事件,不会采用+=,因为委托链的话,非void,会忽略前面的函数,只会返回最后一个函数的结果。

 public class TestEventArgs : EventArgs
{
public string parameters;
public TestEventArgs(string par)
{
6 parameters = par;
}
}

委托事件类

 public class Test
{
3 public delegate string TestHandler(object sender, TestEventArgs tea);//带参数,带返回的委托
4 public event TestHandler TestEvent; //定义事件
5 public string OnTestEvent(TestEventArgs tea)//调用
6 {
7 if (TestEvent != null)
8 {
return TestEvent(this,tea);
}
return null;
12 }
}

注册触发

 static void Main(string[] args)
{
Test model = new Test();
model.TestEvent += model_TestEvent;//注册事件
5 TestEventArgs tea = new TestEventArgs("test");//事件传入参数
6 string result= model.OnTestEvent(tea) ;//事件触发,得到结果
7 Console.WriteLine(result);
}
static string model_TestEvent(object sender, TestEventArgs tea)
{
return "传入的参数是:" +tea.parameters ;
}

补充1、

这里注册和触发同样可以分开,前面的注册类中把model_TestEvent改为

 public virtual string model_TestEvent(objectsender,TestEventArgs tea)//事件执行函数
{
return "传入的参数是:" +tea.parameters;
}
class Program
{
7 static void Main(string[] args)
{
9 Test model = new Test();//实例
10 Listeners listener = new Listeners();//实例监听
11 listener.registerEvent(model);//注册
12 TestEventArgs tea = new TestEventArgs("test"); //事件参数
13 string result= model.OnTestEvent(tea);
14 Console.WriteLine(result);
}
}

补充2、

事件参数类型也可以封装,放在Test类内(OnTestEvent改为privte)。在Test类内加多

 public string InitEvent(string par)
{
TestEventArgs tea = new TestEventArgs(par);
return OnTestEvent(tea);
}
Main就可以改为
static void Main(string[] args)
{
Test model = new Test();
Listeners listener = new Listeners();
listener.registerEvent(model);//监听者注册到Test.这里如果很多不同业务的监听者的话,如何返回所有监听者处理完的信息。修改Listeners类?(单例,管理者类)。
string result = model.InitEvent("test");
Console.WriteLine(result);
}

完毕!多多指教。

关于c#的事件如何使用的更多相关文章

  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. ...

  10. HTML 事件(三) 事件流与事件委托

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

随机推荐

  1. C#:String.Format数字格式化输出 {0:N2} {0:D2} {0:C2}等等

    int a = 12345678; //格式为sring输出//   Label1.Text = string.Format("asdfadsf{0}adsfasdf",a); / ...

  2. selenium2.0(WebDriver) API

    1.1  下载selenium2.0的包 官方download包地址:http://code.google.com/p/selenium/downloads/list 官方User Guide:  h ...

  3. appium移动端测试之滑动(二)

    在ios测试中,需要用到滑动,所以用java封装了一套滑动的方法,不多说,贴代码 /** * 上滑1/4屏幕 */ public void slideUP1_4() { int x = driver. ...

  4. 十三、File Translator怎么写

    ---恢复内容开始--- 1. File Translator可以将信息从maya中导入和导出. 2. 创建一个file translator需要从MPxFileTranslator继承. 3. 函数 ...

  5. python多线程和多进程对比

    1.多线程:开启一个进程test.py ,占用两个cpu  共占用45%左右(top -c ,按1)  多进程:开启两个进程test.py 用两个cpu  90%*2左右 test.py # codi ...

  6. This kind of launch is configured to open the Debug perspective when it suspends.

    This kind of launch is configured to open the Debug perspective when it suspends. 因为设置了断点才会弹出这个,不需要调 ...

  7. 《从零开始做一个MEAN全栈项目》(3)

    欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 上一篇文章给大家讲了一下本项目的开发计划,这一章将会开始着手搭建一个MEAN项目.千里之行,始于足下, ...

  8. android avd sdk root

    网上的方式都失败了... 网上的方式据说是 用于 2.0 左右版本的. 而我们现在主流都用的是  4.0 以上的. 这个http://quantoubao.blog.163.com/blog/stat ...

  9. HBase的伪分布式安装(原创)

    准备工作: 1)安装了伪分布式hadoop:参照http://blog.csdn.net/zolalad/article/details/11472207 2)修改已安装好的hadoop配置文件: a ...

  10. FAST特征点检测features2D

    #include <opencv2/core/core.hpp> #include <opencv2/features2d/features2d.hpp> #include & ...