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 应用中的控件消息传递。

最新文章

  1. Bootstrap 3 简介
  2. 腾讯TOS
  3. vim使用01
  4. mvc-9测试和调试
  5. PHP面向对象学习六 多态
  6. 利用PS自动切图、支持svg且支持icoMoon——再也不用四处去转格式了
  7. 预定义宏_GNUC_ _MSC_VER
  8. SDUT2482二叉排序树
  9. [HTML] <input> 标签
  10. js自执行函数表达式
  11. 冷门却使用的 javascript 技巧
  12. Winform常用开发模式第一篇
  13. AOP:代理思想 (没有考虑到Spring)
  14. HTTP 返回状态代码详解
  15. Servlet常用的接口和类
  16. Ubuntu使用命令行打印文件
  17. leetcode1029
  18. MacOS统计TCP/UDP端口号与对应服务
  19. 安卓socket聊天
  20. iOS - 获取安装所有App的Bundle ID

热门文章

  1. spring beans 源码解读
  2. [UOJ310][UNR #2]黎明前的巧克力
  3. Django基于Form之登录和注册
  4. mongooseim xmpp 服务器docker 安装试用
  5. sqlserver docker 安装部署试用
  6. Oracle12c之 CDB数据库中数据字典架构
  7. bzoj 1927 [Sdoi2010]星际竞速——网络流
  8. Java API 操作Redis
  9. windows环境vagrant修改静态资源文件,centos虚拟机中nginx的web环境下不生效
  10. Redis事务及锁应用