Window Form类有很多的属性/方法和事件,其中事件属于一种发布订阅模式 。订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主体对象。这个主体对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态。 当一个对象的改变需要同时改变其他对象,而且无需关心具体有多少对象需要改变时,就特别适合用此种模式。本文将演示如何在窗体上自定义一个事件(custom event) :

1 自定义一个CustomEventArgs类

  一般自定义的事件都有一个参数,继承自EventArgs.此处我们自定一个CustomEventArgs,类中通过自定义字段来存储参数的值:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace CustomEventsDemo
{
public class CustomEventArgs:EventArgs
{
//自定义字段用于存储值
public object Tag;
public string Message;
public CustomEventArgs()
{ }
public CustomEventArgs(string message, object tag)
{
Message = message;
Tag = tag;
}
}
}

2 自定义一个事件

  接下来我们创建一个FormPublisher窗体,然后用 event EventHandler<CustomEventArgs> customEvent;event EventHandler<CustomEventArgs> customSecondEvent和来自定义两个custom Event事件,它们的事件参数为CustomEventArgs.在窗体加载事件中我们触发两个事件(这个顺序会影响在窗体加载时订阅者的事件响应顺序.如果我们创建一个窗体继承此FormPublisher的话,我们会在此窗体的事件面板中看到下图:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; namespace CustomEventsDemo
{
public partial class FormPublisher : Form
{
//定义两个事件
public event EventHandler<CustomEventArgs> customEvent;
public event EventHandler<CustomEventArgs> customSecondEvent;
public FormPublisher()
{
InitializeComponent();
} private void FormWithCutomEvent_Load(object sender, EventArgs e)
{
//确定自定义事件的执行顺序,继承此窗体的子类窗体加载时的默认顺序
if (customEvent != null)
{
CustomEventArgs customEventArgs = new CustomEventArgs(this.textBox1.Text, "customEvent");
customEvent(this, customEventArgs);
}
if (customSecondEvent != null)
{ CustomEventArgs customEventArgs = new CustomEventArgs(this.textBox1.Text, "customSecondEvent");
customSecondEvent(this, customEventArgs);
} } private void button1_Click(object sender, EventArgs e)
{ this.textBox2.AppendText(this.textBox1.Text + "\r\n");
//this.textBox1.Text = "";
if (customSecondEvent != null)
{
CustomEventArgs customEventArgs = new CustomEventArgs(this.textBox1.Text, "customSecondEvent");
//触发事件
customSecondEvent(this, customEventArgs);
}
if (customEvent != null)
{
CustomEventArgs customEventArgs = new CustomEventArgs(this.textBox1.Text, "customEvent");
//触发事件
customEvent(this, customEventArgs);
}
}
}
}

3 订阅事件

  下面定义一个FormSubscriber窗体来订阅自定义事件,我们要定义另一个窗体的事件,必须要先实例化那个窗体,否则会调用失败:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; namespace CustomEventsDemo
{
public partial class FormSubscriber : Form
{
FormPublisher form = null;
public FormSubscriber()
{
InitializeComponent();
//启动2个窗体
form = new FormPublisher();
form.Visible = true;
//订阅事件
form.customSecondEvent += form_customSecondEvent;
//订阅事件
form.customEvent += form_customEvent;
//把发布窗体实例化后传入第二个订阅窗体中,否则不能订阅
FormSubScriber2 from2 = new FormSubScriber2(form);
from2.Visible = true;
} void form_customSecondEvent(object sender, CustomEventArgs e)
{
this.textBox1.AppendText("Message from Publisher " + e.Message + " from " + e.Tag + "\r\n");
} void form_customEvent(object sender, CustomEventArgs e)
{
this.textBox1.AppendText("Message from Publisher " + e.Message + " from " + e.Tag + "\r\n");
} private void FormSubscriber_Load(object sender, EventArgs e)
{ }
}
}

  另一个窗体也进行订阅:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; namespace CustomEventsDemo
{
public partial class FormSubScriber2 : Form
{ public FormSubScriber2()
{
InitializeComponent();
}
public FormSubScriber2(FormPublisher form)
{
InitializeComponent();
//订阅form自定义事件
form.customEvent += form_customEvent;
}
void form_customEvent(object sender, CustomEventArgs e)
{
this.textBox1.AppendText("Message from Publisher " + e.Message + " from " + e.Tag + "\r\n");
} private void FormSubScriber2_Load(object sender, EventArgs e)
{ }
}
}

如何订阅Form的自定义事件的更多相关文章

  1. vue_组件间通信:自定义事件、消息发布与订阅、槽

    自定义事件 只能用于 子组件 向 父组件 发送数据 可以取代函数类型的 props 在父组件: 给子组件@add-todo-event="addTodo" 在子组件: 相关方法中, ...

  2. javascript 自定义事件 发布-订阅 模式 Event

    * javascript自定义事件 var myEvent = document.createEvent("Event"); myEvent.initEvent("myE ...

  3. Jquery 自定义事件实现发布/订阅

    //用户点击logoff按钮时,广播一个自定义事件,给任何需要保存状态的感兴趣的观察者,然后导航到logoff页面 $('#logoff').click(function(){ $.event.tri ...

  4. 由自定义事件到vue数据响应

    前言 除了大家经常提到的自定义事件之外,浏览器本身也支持我们自定义事件,我们常说的自定义事件一般用于项目中的一些通知机制.最近正好看到了这部分,就一起看了下自定义事件不同的实现,以及vue数据响应的基 ...

  5. 谈谈JS的观察者模式(自定义事件)

    呼呼...前不久参加了一个笔试,里面有一到JS编程题,当时看着题目就蒙圈...后来研究了一下,原来就是所谓的观察者模式.就记下来...^_^ 题目 [附加题] 请实现下面的自定义事件 Event 对象 ...

  6. Javascript之自定义事件

    Javascript自定义事件,其本质就是观察者模式(又称订阅/发布模式),它的好处就是将绑定事件和触发事件相互隔离开,并且可以动态的添加.删除事件. 下面通过实例,一步一步构建一个具体的Javasc ...

  7. C#:委托和自定义事件

    1. 委托概述 “委托”相当于C++中的“函数指针”,委托必须与所要“指向”的函数在“参数”和“返回类型”上保持一致; // 定义Person类 public class Person { publi ...

  8. javascript和jquey的自定义事件小结

    “通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率.” 可以把多个关联但逻辑复杂的操作利用自定义事件的机制灵活地控制好 对象之间通过直接方法调用来交互 1)对象A直接调用 ...

  9. Javascript事件模型系列(四)我所理解的javascript自定义事件

    被我拖延了将近一个月的javascript事件模型系列终于迎来了第四篇,也是我计划中的最后一篇,说来太惭愧了,本来计划一到两个星期写完的,谁知中间遇到了很多事情,公司的个人的,搞的自己心烦意乱浮躁了一 ...

随机推荐

  1. Update: ELCImagePickerController

    March 3rd, 2011 Posted by: Matt Tuzzolo - posted under:Articles » Featured I recently spent some tim ...

  2. CSS多列布局

    × 目录 [1]列宽 [2]列数 [3]列间距[4]列rule[5]跨列[6]列填充[7]多列 前面的话 CSS新增了多列布局特性,可以让浏览器确定何时结束一列和开始下一列,无需任何额外的标记.简单来 ...

  3. 微信开发 -- 搭建基于ngrok的微信本地调试环境

    第一步,安装ngrok客户端 (1)首先先到官网下载个客户端 http://natapp.cn/,选择适合的客户端类型,本人选择的是windows版 (2)下载后,解压,可以看到如下目录: 第二步,开 ...

  4. Cocos2d-x 3.2 学习笔记(八)Action

    Action -动作.所有精灵的表现,人机交互的表现,都是动作.cocos2dx 里面封装的动作可谓是丰富! Action有三个子类 1.FiniteTimeAction类是所有在有限时间能够完成的动 ...

  5. js获取url地址中的参数

    <script type="text/javascript"> function GetQueryString(name) { var reg = new RegExp ...

  6. 这10道javascript笔试题你都会么

    1.考察this var length = 10; function fn() { console.log(this.length); } var obj = {   length: 5, metho ...

  7. Android横竖屏切换及其对应布局加载问题

    第一,横竖屏切换连带横竖屏布局问题: 如果要让软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局. 可以通过以下两种方法来切换布局: 1)在res目录下建立layout-land ...

  8. [software development] 需求分析checklist

    [software development] 需求分析checklist // */ // ]]>   [software development] 需求分析checklist Table of ...

  9. 简单几步把LOGO变字体

    今天学到一招,所以决定简单写写如何利用图标字体生成器IcoMoon把自己制作的图标变成字体,下面以OSChina的图标为例. 一.确保logo转成纯色,并保存为svg格式 因为OSC的logo是绿色带 ...

  10. JS魔法堂:再次认识Function.prototype.call

    一.前言                                大家先预计一下以下四个函数调用的结果吧! var test = function(){ console.log('hello w ...