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

事件处理/生成基础

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.73/5 (7投票s)

2008年1月23日

CPOL

3分钟阅读

viewsIcon

32187

downloadIcon

428

自定义事件生成和处理的快速入门指南

引言

本文档简要介绍了如何编写自定义事件生成器(和处理程序)。本文档的目标读者是刚接触该语言但可能对其他编程语言有一定了解的人。本文档涵盖该主题的详细内容,有关此内容的资源,请参阅 C# 事件实现基础、最佳实践和约定

背景

在 C# 中,事件被定义为“一个成员,它允许对象或类提供通知”,即事件通知系统提供了链接,以便在发生某些操作(通常是用户界面(UI)操作,如按钮单击)时运行代码段。

委托本质上是方法的接口,允许将方法作为参数传递。有关委托的更详细介绍,请参阅 委托和事件 - 未经审查的故事。要为方法创建委托,委托必须完全匹配输入和输出类型参数(但不一定名称),例如;

public delegate void SomeDelegate(String name);

public void okMethod(String s) {
        Console.WriteLine(s);
}

public bool badMethod(String s) {     
        return s.Length > 4;
}

okMethod 可以通过 new SomeDelegate(okMethod) 来封装,因为输入类型和输出类型都匹配;但是 badMethod 不能,因为它具有不匹配的返回值。

使用代码

自定义事件处理需要 3 个类:一个生成器、一个自定义参数封装和一个用于捕获事件的对象(或根据情况,许多捕获类)。在提供的示例代码中,生成器类是 EventGenerator,自定义参数封装是 MyEventArgs,捕获器是 EventCatcher。此外,Program 创建了生成器和捕获器对象并将它们链接起来。

MyEventArgs - 自定义参数封装

public class MyEventArgs : EventArgs
    {
        public delegate void MyHandler(object sender, MyEventArgs e);

        public String someArg;
        public int moreArgs1;
        public double moreArgs2;
    }

MyEventArgs 扩展了 EventArgs,以便事件子系统可以将其作为事件参数进行处理。someArgmoreArgs1moreArgs2 存储要从生成器传递到捕获处理程序的自定义参数,这应根据特定任务进行调整;对于常见的 UI 任务,存在许多 EventArgs,例如 MouseEventArgsMouseButtonEventArgsdelegate MyHandler 定义了自定义事件的处理程序方法的结构;请注意,指定 sender 不是必需的,但这是一个好习惯,并且 sender 对象在事件处理过程中通常很有用。

EventGenerator - 事件生成器

public class EventGenerator {
        public event MyEventArgs.MyHandler SomeEvent;

        public void fireEvent() {
            if (SomeEvent != null) {
                SomeEvent(this, new MyEventArgs());
            }
        }

    }

public event MyEventArgs.MyHandler SomeEvent; 行指定该对象应包含一个名为 SomeEvent 的事件处理程序,允许事件处理程序与 MyEventArgs.MyHandler 委托匹配。fireEvent 方法虽然不是必需的(其内容可以内联到其他代码中),但它展示了事件对象如何触发事件,即为每个附加的事件处理程序生成一个事件。new MyEventArgs() 可以替换为已设置了内部属性的 MyEventArgs 对象,从而提供更有用的数据传输。

EventCatcher - 事件处理

public class EventCatcher {

        public void g_SomeEvent(object sender, MyEventArgs e) {
            Console.WriteLine("It happened in EventCatcher...");
        }

    }

事件处理仅需要创建一个与事件关联的委托匹配的方法;这可以由 Microsoft Visual Studio(或其他)编辑器在附加到事件生成器时自动完成。

Program - 系统链接

        static void Main(string[] args) {
            EventGenerator g = new EventGenerator();
            EventCatcher c = new EventCatcher();

            g.SomeEvent += new MyEventArgs.MyHandler(g_SomeEvent);
            g.SomeEvent += new MyEventArgs.MyHandler(c.g_SomeEvent);

            g.fireEvent();

            Console.ReadLine();
        }

        static void g_SomeEvent(object sender, MyEventArgs e) {
            Console.WriteLine("It happened in Program...");
        }

Main 方法通过 g.SomeEvent += new MyEventArgs.MyHandler(c.g_SomeEvent) 将事件生成器对象 g 链接到事件捕获器对象 c;此行访问 g.SomeEvent 事件处理程序,并向其添加一个封装了 c.g_SomeEvent 方法的新 MyHandler 委托。请注意,也可以将静态方法作为事件处理程序添加,如 g.SomeEvent += new MyEventArgs.MyHandler(g_SomeEvent)。最后,要触发事件,请调用 g.fireEvent()

关注点

编写此类代码时,您不会学到任何有趣/好玩/烦人的东西。也不会做任何特别聪明或疯狂或古怪的事情。然而,这段代码代表了事件系统的基本用法,所以抛弃旧的 Java 风格,学习吧。

历史

版本 1.000,事件系统的基本示例,完成。

© . All rights reserved.