自学内容网 自学内容网

C#事件驱动编程:标准事件模式完全指南

事件驱动是GUI编程的核心逻辑。当程序被按钮点击、按键或定时器中断时,如何规范处理事件?.NET框架通过EventHandler委托给出了标准答案。

🔍 一、EventHandler委托:事件处理的基石

public delegate void EventHandler(object sender, EventArgs e);

参数解析

  • object sender → 事件源对象(任意类型)
  • EventArgs e → 事件数据容器(默认为空)
    核心特性
  • 强制统一签名:所有事件处理器必须匹配此参数结构
  • 返回值必须为void
  • EventArgs是空壳基类,实际数据需通过派生类扩展

💡 设计意义:通过标准化参数,实现事件处理接口的统一化,避免签名混乱。

⚙️ 二、基础事件实现(无数据传递)

// 发布者 
class Incrementer {
    public event EventHandler CountedADozen;  // 声明标准事件 
    
    public void DoCount() {
        for(int i=1; i<100; i++)
            if(i%12 == 0 && CountedADozen != null)
                CountedADozen(this, null);  // 触发事件(无数据)
    }
}
 
// 订阅者 
class Dozens {
    void IncrementDozensCount(object source, EventArgs e) {
        DozensCount++;  // 忽略参数e 
    }
}

适用场景:仅需事件通知,无需传递额外数据(如界面按钮点击)

🚀 三、扩展事件数据:自定义EventArgs

步骤详解:

1️⃣ 创建派生类存储数据

public class IncrementerEventArgs : EventArgs {
    public int IterationCount { get; set; }  // 自定义数据属性 
}

2️⃣ 使用泛型委托声明事件

class Incrementer {
    // 泛型委托绑定自定义参数类型 
    public event EventHandler<IncrementerEventArgs> CountedADozen;
}

3️⃣ 触发事件时传递数据

public void DoCount() {
    var args = new IncrementerEventArgs();  // 创建数据对象 
    for(int i=1; i<100; i++) {
        if(i%12 == 0 && CountedADozen != null) {
            args.IterationCount = i;  // 设置数据 
            CountedADozen(this, args);  // 传递数据对象 
        }
    }
}

4️⃣ 订阅者接收数据

void IncrementDozensCount(object source, IncrementerEventArgs e) {
    Console.WriteLine($"触发位置:{e.IterationCount}");  // 使用自定义数据 
}

⚠️ 命名规范:自定义类名需以EventArgs结尾

🔄 四、事件处理程序管理

动态增删处理器:

// 添加处理器 
p.SimpleEvent += s.MethodA;  
p.SimpleEvent += s.MethodB;
 
// 移除指定处理器 
p.SimpleEvent -= s.MethodB;  

关键规则:

  • 同个处理器多次注册时,-=只移除最后一次注册
  • 事件触发前必须检查null(避免空引用异常)
  • 线程安全场景需使用Invoke同步调用
场景方案示例
无数据传递原生EventHandler按钮点击事件
需传递数据EventHandler+自定义EventArgs进度条数值更新
多订阅者管理+=/-=动态注册动态加载模块
// 终极模板 
public event EventHandler<CustomEventArgs> MyEvent;
public class CustomEventArgs : EventArgs { ... }

🚀 行动建议:

  • 立即重构旧事件代码,采用标准模式
  • 复杂数据场景务必使用自定义EventArgs
  • 关键事件添加try-catch异常处理

原文地址:https://blog.csdn.net/weixin_42291376/article/details/149109249

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!