.NET框架为事件定义了一个标准模式,它的目的是保持框架和用户代码之间的一致性。

标准事件的模式核心是SystemEventArgs——预定义的没有成员的框架类(不同于静态Empty属性)

EventArgs表示包含事件数据的类的基类,并提供用于不包含事件数据的事件的值。用于为事件传递信息的基类。

在下面例子中,我们定义EventArgs的子类,用于事件PriceChanged被引发时,传递新旧Price值:

    public class PriceChangedEventArgs : EventArgs
{
public readonly decimal LastPrice;
public readonly decimal NewPrice; public PriceChangedEventArgs(decimal lastPrice, decimal newPrice)
{
LastPrice=lastPrice;
NewPrice= newPrice;
}
}

考虑到复用性,EventArgs子类根据它包含的内容命名(而非根据将被使用的事件命名)。

选择或定义事件的委托,需遵循三条原则:

  • 委托必须以void作为返回值
  • 委托必须接受两个参数:第一个是object类,第二个是EventArgs的子类。
  • 委托的名称必须以EventHandler结尾

完整例子:

class Test
public static void Main()
{
InitializeComponent();
Stock stock = new Stock("THPW");
stock.Price = 27.10M;
//注册PriceChanged事件
stock.PriceChanged += stock_PriceChanged;
stock.Price = 31.59M;
} static void stock_PriceChanged(object sender, PriceChangedEventArgs e)
{
if ((e.NewPrice - e.LastPrice) / e.LastPrice > 0.1M)
{
Console.WriteLine("Alert,10% stock increase!");
}
}
} public class Stock
{
string symbol;
decimal price; public Stock(string symbol)
{
this.symbol = symbol;
}

//定义委托事件
public event EventHandler<PriceChangedEventArgs> PriceChanged;

protected virtual void OnPriceChanged(PriceChangedEventArgs e)
{
if (PriceChanged != null) PriceChanged(this, e);
} public decimal Price
{
get { return price; }
set
{
if (price == value) return;
            price = value;
          OnPriceChanged(new PriceChangedEventArgs(price, value));

            }
}
} public class PriceChangedEventArgs : EventArgs
{
public readonly decimal LastPrice;
public readonly decimal NewPrice; public PriceChangedEventArgs(decimal lastPrice, decimal newPrice)
{
LastPrice=lastPrice;
NewPrice= newPrice;
}
}

如果事件不传递额外的信息,可以使用预定义的非泛化委托EventHandler。如下所示:

    class Test
{
public static void Main()
{
InitializeComponent();
Stock stock = new Stock();
stock.Price = 27.10M;
//注册PriceChanged事件
stock.PriceChanged += stock_PriceChanged;
stock.Price = 31.59M;
} static void stock_PriceChanged(object sender, EventArgs e)
{
Console.WriteLine("价格变换了!");
}
} public class Stock
{
decimal price; public event EventHandler PriceChanged; protected virtual void OnPriceChanged(EventArgs e)
{
if (PriceChanged != null) PriceChanged(this, e);
} public decimal Price
{
get { return price; }
set
{
if (price == value) return;
price = value; //OnPriceChanged(new EventArgs()); OnPriceChanged(EventArgs.Empty);
}
}
}

注意:

上面例子中事件除了传递已发生信息,没有传递其他信息。

你可以使用 OnPriceChanged(new EventArgs()) 来完成事件的传递。

为了避免对EventArgs不必要的初始化,建议使用EventArgs.Empty属性。使用这样一个“空的”静态引用的对象,避免多余地去创建一个新对象。

微软的大部分控件所抛出的事件都有两个参数,第一个是 object 类型的,第二个是 EventArgs 类型的。

你从EventArgs  e那里得不到任何此次事件相关需要传递的信息,真正传递的信息都在sender中。

C# 标准事件模式的更多相关文章

  1. W3C对DOM2.0定义的标准事件

    DOM2.0模型将事件处理流程分为三个阶段: 一.事件捕获阶段, 二.事件目标阶段, 三.事件起泡阶段. 具体如图(图片来源于网络,侵删) 事件捕获:当某个元素触发某个事件(如onclick),顶层对 ...

  2. C#代码:用事件模式实现通知

    事件提供了一种标准的机制来通知监听者..NET的事件模式使用了事件语法来实现观察者模式.任意数量的客户对象都可以将自己的处理函数注册到事件上,然后处理这些事件.这些客户对象不需要再编译期就给出.时间也 ...

  3. 【转载】详细解读C#中的 .NET 弱事件模式

    你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处理中展 ...

  4. C#中的 .NET 弱事件模式

    引言 你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处 ...

  5. 标准IDispose模式浅析

    DoNet资源 众所周知,.Net内存管理分托管资源和非托管资源,把内存中的对象按照这两种资源划分,然后由GC负责回收托管资源(Managed Resource),而对于非托管资源来讲,就需要程序员手 ...

  6. CUDA 标准编程模式

    前言 本文将介绍 CUDA 编程的基本模式,所有 CUDA 程序都基于此模式编写,即使是调用库,库的底层也是这个模式实现的. 模式描述 1. 定义需要在 device 端执行的核函数.( 函数声明前加 ...

  7. 如何给ActiveX控件添加“事件”“属性”“标准事件”“自定义事件”等一些相关操作

    上一篇小编带大家熟悉了一下ActiveX的建立以及相关的概念,(http://blog.csdn.net/u014028070/article/details/38424611) 本文介绍下如何给控件 ...

  8. C#的内存管理原理解析+标准Dispose模式的实现

    本文内容是本人参考多本经典C#书籍和一些前辈的博文做的总结 尽管.NET运行库负责处理大部分内存管理工作,但C#程序员仍然必须理解内存管理的工作原理,了解如何高效地处理非托管的资源,才能在非常注重性能 ...

  9. [转]改善C#程序的建议4:C#中标准Dispose模式的实现

    需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...

随机推荐

  1. IIS上发布站点后URL重写失效的解决方法

    在发布网站时URL重写有可能会失效,如果失效的话就需要您设置一下IIS:1.Windows XP系统或Windows 2003系统等使用以下方法:>打开IIS,主目录-〉配置-〉映射-〉在窗体左 ...

  2. 仿微信客户端 帧布局中加入fragment

    学习内容来自“慕课网” 这里用Fragment来实现APP主界面 思路: 底部横向排列4个LinearLayout,每个LinearLayout包含一个图片按钮和一个文字 1.默认显示第一个功能(微信 ...

  3. Halcon对文件的创建、读取、写入、删除等操作总结

    Halcon可以操作普通文本文件,也可以操作二进制文件.如下图所示,只需要设置“FileType”参数的取值即可明确是操作文本文件还是二进制文件: 下面的程序是操作一个.txt文本文件的完整代码: * ...

  4. PAT 1047 编程团体赛(代码)

    1047 编程团体赛(20)(20 分) 编程团体赛的规则为:每个参赛队由若干队员组成:所有队员独立比赛:参赛队的成绩为所有队员的成绩和:成绩最高的队获胜. 现给定所有队员的比赛成绩,请你编写程序找出 ...

  5. chrome 调试工具的使用

    Elements chrome devtools 中 Elements panel 是审查 dom 元素和 css 的, 可以实时修改 dom/css. windows: ctrl + shift + ...

  6. ShowMsg函数

    ShowMsg():显示提示信息,跳转到相应页面 例子: ShowMsg(,);

  7. Zookeeper 系列(五)Curator API

    Zookeeper 系列(五)Curator API 一.Curator 使用 Curator 框架中使用链式编程风格,易读性更强,使用工程方法创建连接对象使用. (1) CuratorFramewo ...

  8. Python 函数式编程和OOP编程 0001测试

    # encoding: utf- stu1 = { ' } stu2 = { ' } def stu_score(stu_score): print ('%s , %s ' % ( stu_score ...

  9. event对象的理解

    0.给对象绑定事件准确的说是给对象事件绑定事件函数 1.event:事件对象,当一个事件发生的时候,和当前这个对象发生的事件有关的信息都会被i临时保存到event对象中 2.event对象必须在一个事 ...

  10. SEO方式之HTTPS 访问优化详解

    SEO到底要不要做HTTPS?HTTPS对SEO的重要性 正方观点 1.HTTPS具有更好的加密性能,避免用户信息泄露: 2.HTTPS复杂的传输方式,降低网站被劫持的风险: 3.搜索引擎已经全面支持 ...