65.9K
CodeProject 正在变化。 阅读更多。
Home

面向初学者的事件和自定义 EventArgs 详解

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.56/5 (7投票s)

2008年11月6日

CPOL

4分钟阅读

viewsIcon

40640

downloadIcon

296

了解如何将事件附加到对象以及如何为初学者创建自定义 EventArgs

引言

本文旨在帮助初学者理解如何定义事件以及如何创建自定义事件参数 (EventRrgs) 来传递事件特定的数据。

背景

本文面向初学者,旨在帮助他们真正理解事件的概念以及如何应用它。

在开始阅读本文之前,我建议您先快速了解一下事件和委托的定义和理解。

使用代码

下载本文并将其保存在硬盘上。然后使用 Visual Studio 2005 打开现有项目。转到 文件->打开->网站

什么是事件?

定义 1:C# 中的事件是一种特殊的委托类型变量。
定义 2:事件是一种通知,表示系统中发生了某事。

那么,我们从这些定义中得到了什么?

从第一个定义可以清楚地看出,在声明事件之前,我们必须先声明一个委托,因为事件是委托类型的变量。从第二个定义可以清楚地看出,事件只有在系统中发生一些有趣的事情时才会触发。

什么是“有趣的事情”?

有趣的事情可以是任何事情。正如我们所知,按钮点击、复选框选中、下拉列表选项更改都是事件。同样,我们可以定义自己的事件。例如,向 ArrayList 添加一个项(我们可以称之为 `arrayList_added` 事件)。

示例说明

我有一个 ArrayList 对象,我想在向列表中添加项时,它应该发布(触发或激发事件的对象称为发布者类,订阅者称为订阅者类——又称发布者-订阅者模型)一个事件,并且该事件将由定义了 EventHandler 的订阅者类来订阅。注意:当发布者类的对象激发事件时,任何数量的订阅者类都可以订阅该事件。

System.Collections.ArrayList 类在向列表中添加新项时不会触发任何事件。那么,我们在添加时如何触发事件呢?

所以,这就是你们现在面临的问题,对吧?很简单……让那个 ArrayList 保持原样。我们只需创建自己的自定义 ArrayList 类,然后重写 Add 方法即可。

public virtual int Add(object value); 

这是 ArrayList Add 方法的签名。所以我们将重写这个虚拟方法。

但是怎么做?

因此,发布者类或自定义 ArrayList 类如下所示:

public delegate void ArrayListItemAddEventHandler(object sender); 
public class MyArrayList:ArrayList 
{ 
	    public event ArrayListItemAddEventHandler added; 
	    public override int Add(object value) 
	    { 
                 if (added != null) added(this); 
	        return base.Add(value); 
             } 
}

我们在这里做了什么?

正如我之前提到的,我们只是重写了 Add 方法。在调用基类的 Add 方法之前,我们触发了事件。我们定义了一个委托,事件应该是该委托的类型。现在,每当我们尝试向列表中添加任何内容时,CustomArrayList 都会触发事件。这是肯定的。

What Next?

现在我们需要设计订阅者类,它将订阅事件并在收到通知时执行有用的操作。因此,很明显订阅者类必须有一个 EventHandler(只是一个函数或方法,其签名与委托匹配)。

public class SubscriberClass
{
        public void AddedEventHandler(object sender)
        {
            MessageBox.Show("An item has been added to the List");
        }
    
}

因此,这就是订阅者类。现在我们可以编写一个 main 方法来演示如何实际订阅通知。

static void Main(string[] args)
        {
            MyArrayList list = new MyArrayList();
            SubscriberClass sc = new SubscriberClass();
            //so the subscriber class subscribes the event here
            list.added += new ArrayListItemAddEventHandler(sc.AddedEventHandler);
            //now adding something into the Custom Arraylist
            list.Add(1212);
        }

一旦项被添加到 CustomArrayList 中,它就会触发“added”事件。由于订阅者类已经订阅了事件,因此将调用 EventHandler,并且消息框将显示“已添加项”的消息。现在我认为这对所有人来说都足够清楚了。现在,假设我们也想在消息框中显示更多信息,例如我们添加了哪个数字。

该怎么办?众所周知,EventArgs e 不会向我们提供有关列表中已添加项的信息。

解决方案是我们可以继承 EventArgs 类并创建我们自己的 EventArgs 类,例如 ArrayListItemAddEventArgs。

它看起来像什么?

 public class ArrayListItemAddEventArgs : EventArgs
    {
        public int addedItem;//this will keep track of currently added item to the list
        public ArrayListItemAddEventArgs(int item)
        {
            addedItem = item;
        }
    }

够了。

我们还需要根据委托签名的更改来更改委托签名以及 EventHandler 定义。

public delegate void ArrayListItemAddEventHandler(object sender,ArrayListItemAddEventArgs e); 

所以我们只需向 add 方法添加一行代码。

ArrayListItemAddEventArgs e = new ArrayListItemAddEventArgs((int)value); 

因此,自定义 ArrayList 类将如下所示:

 public delegate void ArrayListItemAddEventHandler(object sender,ArrayListItemAddEventArgs e); 
    public class MyArrayList:ArrayList
    {
        public event ArrayListItemAddEventHandler added;
        
        
        public override int Add(object value)
        {
            ArrayListItemAddEventArgs e = new ArrayListItemAddEventArgs((int)value);
            if (added != null) added(this,e);        
            return base.Add(value);
        }
    }

订阅者类

  public class SubscriberClass
    {
        public void AddedEventHandler(object sender,ArrayListItemAddEventArgs e)
        {
            MessageBox.Show(string.Format("The item  {0} has been added to the List!", e.addedItem));
        }
    }

现在我们可以轻松地像这样在消息框中显示添加的项:

MessageBox.Show("An item has been added to the List"+e.addedItem);
所以,朋友们,我想你们现在都明白了如何玩转事件了。

如何在 .NET 中挂接事件处理程序?

在 .NET 中,默认的委托签名是:

protected void Eventhandler(object sender,EventArgs e){}

现在,假设我们有一个按钮控件,并且有另一个类将订阅该按钮的 `clicked` 事件。该类在其自身类中定义了 `ButtonIsClicked` 事件处理程序,其签名与默认委托签名匹配。

protected void ButtonIsClicked(object sender,EventArgs e){}

在这种情况下,我们只需添加一行代码。

button1.Clicked+=new System.Eventhandler(ButtonIsClicked);

因此,当 Clicked 按钮时,`Button_Clicked` 和 `ButtonIsClicked` 这两个方法都会被调用。

注意:请根据您的喜好投票这篇文章,如果您有任何困惑,请随时回来并在此处发表评论。 

© . All rights reserved.