head first C#学习笔记:如何创建事件以及事件处理程序

编写一个棒球模拟系统。要达到的效果:输入棒球的轨迹和距离,输出其他对象的响应(投球手能否接到球,现场观众如何反应,裁判如何反应等。)

思路:首先得有一个Ball对象。它只负责自己是否被击中(事件发生),根本不管球出去之后,由谁来接住球。那么对于其他对象(投球手、裁判、现场观众),都希望能够订购这种特定事件(监听事件),就是说当球被击中这一事件发生之后,能得到通知,然后各自做出反应。
这里写图片描述

类似这样的例子是很多的,GOF对它进行了抽象,称为 Observer设计模式: Observer 设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新。

在创建这个事件之前,先看看我们平常用的最普通的按钮click事件完整的是怎样创建的。
一、首先在内部已经集成好的一个类里声明如下
public event EventHandler Click;
以此来通知其他对象,存在这么一个click事件,以便其他对象来订购这个事件。
其中,public表明允许其他类中的对象访问。EventHandler是为了告诉其他对象他们的事件处理方法应该是什么样子的:应该是有两个参数:object sender, EventArgs e.
这里写图片描述
二、然后在Form1.designer.cs中声明如下
this.playBallButton.Click += new System.EventHandler(this.playBallButton_Click);
其中,playBallButton是要触发事件的那个按钮名称。
1. this.playBallButton.Click这告诉C#将这个事件处理程序关联到playBallButton引用所指向的对象的click事件中。
2.+=操作符告诉C#为一个事件关联一个事件处理程序。
3. new System.EventHandler(this.playBallButton_Click)指定了事件处理方法名称、参数。
这里写图片描述
三、最后在Form1. cs中实现事件处理程序:
这里写图片描述
看完了click事件的完整创建过程,下面开始着手写ballInPlay的事件:
1. Form1中:

public partial class Form1 : Form
    {
        Ball ball = new Ball();
        Pitcher pitcher;
        Fan fan;

        public Form1()
        {
            InitializeComponent();
            pitcher = new Pitcher(ball);
            fan = new Fan(ball);
        }

        private void playBallButton_Click(object sender, EventArgs e)//按钮按下进入这个方法
        {
            BallEventArgs ballEventArgs = new BallEventArgs(
                (int)trajectory.Value, (int)distance.Value);//建立一个表示参数的对象。
            ball.OnBallInPlay(ballEventArgs);//调用ball类中的OnBallInPlay方法
        }
    }

2.Ball这个类中:

class Ball
    {
        public event EventHandler<BallEventArgs> BallInPlay;//模仿click事件,用event关键字声明事件,通知其他类有这么一个BallInPlay事件。

        public void OnBallInPlay(BallEventArgs e)//创建事件的一个方法。当playBallButton按钮按下去之后进入这个方法
        {
            EventHandler<BallEventArgs> ballInPlay = BallInPlay;//先复制给另一个变量,然后检查是否为null,再用它产生事件。
            if (ballInPlay != null)
                ballInPlay(this, e);//经过这一句就产生BallInPlay事件了?
        }
    }

3.Pitcher这个类中:

class Pitcher
    {
        public Pitcher(Ball ball)
        {
            ball.BallInPlay += ball_BallInPlay;//对象来订购事件
        }

        void ball_BallInPlay(object sender, EventArgs e)//事件处理
        {
            if (e is BallEventArgs)
            {
                BallEventArgs ballEventArgs = e as BallEventArgs;//向下强制转换,以便使用它的属性
                if ((ballEventArgs.Distance < 95) && (ballEventArgs.Trajectory < 60))
                    CatchBall();
                else
                    CoverFirstBase();
            }
        }

        private void CatchBall()
        {
            Console.WriteLine("Pitcher: I caught the ball");
        }

        private void CoverFirstBase()
        {
            Console.WriteLine("Pitcher: I covered first base");
        }
    }

下面关键地方我们单步运行一下,看一下事件之间是怎样联系起来的
1.运行到ballInPlay(this, e);后点击单步运行;
这里写图片描述
2.之后跳到这里:第一个订购此事件的类中:Pitcher类。
这里写图片描述
3.然后到第二个订购此事件的类中:fan类中
这里写图片描述
这样,就把各个类的事件处理程序(订购过同一事件)一个接一个地串起来关联到这个事件。

后来看到一篇讲解“事件”更加通俗易懂的文章,在下一篇《C# 中的委托和事件》中:当然,这篇文章有点长,先是讲解了委托,然后再引出事件,虽然有点长,但是细细看下来收获会很大。

本篇代码下载:
http://download.csdn.net/detail/u013480539/9668446

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值