C# event 事件学习

运行环境:Window7 64bit,.NetFramework4.61,C# 6.0; 编者:乌龙哈里 2017-02-26


章节:

  • 简单事件编写
  • 模拟 WPF 控件传递消息

正文:

一、简单事件编写:

对于 C# 中的事件 event ,我的理解是:通过委托(delegate)来调用另一个类的 method。
比如下面有个电台的类:

class Station
{
    private string info;
    public Station(string s)=>info=s;
    public void Broadcast()=> Console.WriteLine(info);
}

现在手头上我有个 Radio 的类,我怎么直接调用 Station.Broadcast() 呢?
方法一,可以用反射(Reflaction),但是这样太笨重了。
方法二,在 Radio 类中直接写 Station 的实例,比如 station1.Broadcast() ,但这样的设计很不灵活,万一碰到另外一个实例名叫 station2 的就歇菜了。
这时候就需要事件(event)了。下来我们就按步骤一步一步来建立一个 Radio 的类:

1、声明一个委托 delegate 指向想调用的方法。
这里是 Broadcast()。写委托的时候注意参数必须和要调用的方法类型一致。

public delegate void StationBroadcast();

2、用关键字 event 声明这个委托的事件。

public event StationBroadcast PlayEvent;

3、写一个方法来调用这个事件。

public void OnPlay()
{
    PlayEvent();
    Console.WriteLine();
}

好了,到这步为止,我们就设好一个能调用 Station.Broadcast() 的类 Radio。下面是整个 Radio 类的写法:

class Radio
{
    public delegate void StationBroadcast();
    public event StationBroadcast PlayEvent;
    public void OnPlay()
    {
        PlayEvent();
        Console.WriteLine();
    }
}

下来就是如何运用了。Radio 的 PlayEvent 要加载和弃掉事件,用符号 +=,-=。

示例1:

Station fm101 = new Station("fm101 is on air ~~");
Station fm97 = new Station("~~ here is fm97");
Radio radio = new Radio();
//只加载fm101
radio.PlayEvent += fm101.Broadcast;
radio.OnPlay();
//只加载fm97
radio.PlayEvent -= fm101.Broadcast;
radio.PlayEvent += fm97.Broadcast;
radio.OnPlay();
//增加一个 fm101
radio.PlayEvent+=fm101.Broadcast;
radio.OnPlay();
//多加载一次fm101
radio.PlayEvent += fm101.Broadcast;
radio.OnPlay();

/*运行结果:
fm101 is on air ~~

~~ here is fm97

~~ here is fm97
fm101 is on air ~~

~~ here is fm97
fm101 is on air ~~
fm101 is on air ~~
*/

这样写,只要符合返回值为 void 的,不带参数的函数,不管叫什么名字,我们都可以调用。
比如我们这个 Radio 更高级些,还能放MP3,增加一个 MP3的类:

class MP3
{
    public void Play() => Console.WriteLine("yoyo !");
}

下来我们一样调用:

MP3 mp3 = new MP3();
radio.PlayEvent += mp3.Play;
radio.OnPlay();

/*运行结果:
yoyo !
*/

二、模拟 WPF 控件传递消息:

在写 Wpf 程序的时候,Button 的响应 Click 事件一般如下:

private void Button_Click(object sender, RoutedEventArgs e);

下来我们就模拟一下这个响应的过程。以下程序都是控制台应用,并不是 Wpf 应用。
首先有个消息类供控件来传递:

class MsgArgs
{
    public string str;
}

接下来 模拟窗口类 Win 里面有控件 Button,还有发生按钮 click 改变消息 MsgArgs 内容的方法:

class Win
{
    public Button button1;
    public void OnClick(object sender,MsgArgs e)
    {
        e.str = "button click";
    }
}

然后根据上面所说的步骤,建立一个 Button 类:

class Button
{
    public delegate void OnClickHandler(object o,MsgArgs e);
    public event OnClickHandler OnClick;
    public void Click(object sender,MsgArgs e)
    {
        OnClick(sender,e);
        Console.WriteLine(e.str);
    }
}

接下来就是具体调用了,如下:

Win win = new Win();
Button btn = new Button();
MsgArgs msg = new MsgArgs();

win.button1 = btn;
btn.OnClick += win.OnClick;
btn.Click(btn, msg);

模拟完毕,简单再现了 Wpf 应用中的控件消息传递。

C# event 事件学习的更多相关文章

  1. event事件学习小节

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. JS学习笔记9之event事件及其他事件

    -->鼠标事件-->event事件对象-->默认事件-->键盘事件(keyCode)-->拖拽效果 一.鼠标事件 onclick ---------------鼠标点击事 ...

  3. JavaScript学习 - 基础(七) - DOM event(事件)

    DOM event(事件) 定义事件: // 定义事件: //方式一,直接在标签上定义事件 // 方式二: var a11 = document.getElementsByName('a11')[0] ...

  4. Mysql事件学习

    出自:http://blog.chinaunix.net/uid-20639775-id-3323098.html Mysql事件学习 在系统管理或者数据库管理中,经常要周期性的执行某一个命令或者SQ ...

  5. 简单总结焦点事件、Event事件对象、冒泡事件

    每学习一些新的东西,要学会复习,总结和记录. 今天来简单总结一下学到的几个事件:焦点事件.Event事件对象.冒泡事件 其实这几个事件应该往深的说是挺难的,但今天主要是以一个小菜的角度去尝试理解一些基 ...

  6. C#委托与事件学习笔记

    委托事件学习笔记 本文是学习委托和事件的笔记,水平有限,如有错漏之处,还望大神不吝赐教. 什么是委托?从字面意思来解释,就是把一个动作交给别人去执行.在实际开发中最常用的就是使一个方法可以当做一个参数 ...

  7. Mysql event事件用法

    公司的数据库需要进行定期删除数据,需要用到mysql event事件,学习和梳理这块知识. 1查看event是否开启 SHOW VARIABLES LIKE 'event_scheduler'; 2开 ...

  8. CDI(Weld)高级<4> Event(事件) (转)

    目录[-] 1. Event payload(事件的有效载入) 2. Event observers(event的观察者) 3. Event producers(event生产者) 4.Annotat ...

  9. Caddy源码阅读(二)启动流程与 Event 事件通知

    Caddy源码阅读(二)启动流程与 Event 事件通知 Preface Caddy 是 Go 语言构建的轻量配置化服务器.https://github.com/caddyserver/caddy C ...

随机推荐

  1. huawei机试题目

    1/*输入一个字符串,输出这个字符串中单词的字典排序*/ bool cmp(char* a,char* b){ ? true:false; } void sortWord(char* str) { v ...

  2. usb udev

    [root@localhost ~] # udevadm monitor monitor will print the received events for: UDEV - the event wh ...

  3. 新Eclipse安装与配置 【来源网络根据实际情况自己补充】

    [第一次更新:20161108:http://blog.csdn.net/vvanity/article/details/51036678] Eclipse的官网地址:http://www.eclip ...

  4. onerror="javascript:this.src='images/defaultUpload.png';"【容易导致死循环报错】

    当无法找到默认图片时,onerror="javascript:this.src='images/defaultUpload.png';"容易导致死循环报错

  5. 每天一个linux命令:【转载】ls命令

    ls命令是linux下最常用的命令.ls命令就是list的缩写,缺省下ls用来打印出当前目录的清单,如果ls指定其他目录,那么就会显示指定目录里的文件及文件夹清单. 通过ls 命令不仅可以查看linu ...

  6. 使用Session防止表单重复提交(不考虑多服务器)

    在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 原理:  1, ...

  7. 二次剩余-Cipolla

    二次剩余 \(Cipolla\) 算法 概述 大概就是在模 \(p\) 意义下开根号,如求解方程\(x^2\equiv n(mod\ p)\). 这里只考虑 \(p\) 为素数的情况.若 \(p=2\ ...

  8. (IOCP)-C#高性能Socket服务器的实现

    C#高性能Socket服务器的实现(IOCP) https://www.jianshu.com/p/c65c0eb59f22 引言 我一直在探寻一个高性能的Socket客户端代码.以前,我使用Sock ...

  9. ASP.NET中几种加密方法

    下面就是ASP.NET中几种加密方法.加密算法有两种,也就是上面提到的MD5和SHA1,这里我举的例子是以MD5为例,SHA1大致相同,只是使用的类不一样. MD5的全称是Message-Digest ...

  10. 【oracle】Oracle中as关键字

    在Oracle中as关键字不能用于指定表的别名 在Oracle中指定表的别名时只需在原有表名和表的别名之间用空格分隔即可 但as关键字可以用于指定列的别名 但在存储过程中如果列的别名与原有列名相同,在 ...