初步了解事件
定义:单词Event,译为“事件”
·《牛津词典》中的解释是“a thing that happens,especially something important”
·通顺的解释就是“能够发生的什么事情”
·角色:是对象或类具备通知能力的成员
·(中译)事件(Event)是一种使对象或类能够提供通知的成员
·(原文)An event is a member that enables an object or class to provide notifications.
·“对象O拥有一个事件E”想表达的思想是:当事件E发生的时候,O有能力通知别的对象
·使用:用于对象或类间的动作协调与信息传递(消息推送)
·事件的功能
通知+可选的事件参数(即详细信息)
·事件模型( event model)中的两个“5”
·"发生→响应"中的五个部分————闹钟响了你起床、孩子饿了你做饭…这里隐含着订阅关系
·"发生→响应"中的五个动作————(1)我有一个事件→(2)一个人或者一群人关心我的这个事件→(3)我的这个事件发生了→(4)关心这个事件的人依次通知到→(5)被通知到的人根据拿到的事件信息(又称“事件数据”、“事件参数(EventArgs)”、“通知”)对事件进行响应(“又称作事件处理”)。
·提示:
·事件多用于桌面、手机登开发客户端编程,因为这些程序经常是用户通过事件来“驱动”的
·各种编程语言对这个机制的实现方法也不尽相同
·java语言里没有事件这种成员,也没有委托这种数据类型。Java的“事件”是使用接口来实现的
·MVC、MVP、MVVM等模式,是事件模式更高级、更有效的“玩法”
·日常开发的时候,使用已有事件的机会比较多,自己声明事件的机会比较少,所以先学使用
事件的应用
·实例演示
派生(继承)与拓展(extends)
事件模型的五个组成部分
1.事件拥有者(event source,对象)
2.事件成员(event,成员)
3.事件的响应者(event subscriber,对象)
4.事件处理器(event handler,成员)
5.事件订阅————把事件处理器与事件关联在一起,本质上是一种以委托为基础的“约定”
例子:
一个事件有两个事件处理器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace ConsoleApp37
{
class Program
{
static void Main(string[] args)
{
Timer timer = new Timer();///事件的拥有者
timer.Interval = 1000;///每间隔1秒就触发Elapsed事件
///timer.Elapsed 闪电图标的就是事件(小方块是属性,小扳手是属性 ),Elapsed表示度过一段时间就会触发,时间长短由我们来定
Boy boy = new Boy();
Girl girl = new Girl();
timer.Elapsed += boy.Action;///+=表示订阅事件响应者,boy.Action就是这个事件的响应者,可以用VS的程序修补自动生成
timer.Elapsed += girl.Action;
timer.Start();
Console.ReadLine();
}
class Boy
{
internal void Action(object sender, ElapsedEventArgs e)///事件处理器
{
Console.WriteLine("jump!");
}
}
class Girl
{
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Sing!");
}
}
}
}
例2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ConsoleApp38
{
class Program
{
static void Main(string[] args)
{
Form form = new Form();///事件拥有者
Controller controller = new Controller(form);//事件的响应者
form.ShowDialog();
}
}
class Controller
{
private Form form;///私有字段
public Controller(Form form)
{
if (form!=null)
{
this.form = form;
this.form.Click += this.FormClicked;///vs自动生成,click是事件,事件订阅
}
}
private void FormClicked(object sender, EventArgs e)///此处与之前的elapsed事件处理器不同,不能拿影响Elapsed事件的时间处理器去响应click事件,因为遵循的约束不同,所以不能通用
{
this.form.Text = DateTime.Now.ToString();///事件处理器
}
}
}
例三
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ConsoleApp39
{
class Program
{
static void Main(string[] args)
{
MyForm form = new MyForm(); //form事件拥有者,同时也是事件的响应者
form.Click += form.FormClicked;//click事件,"+=" 订阅
form.ShowDialog();
}
}
class MyForm : Form//在原有类基础上增加功能,叫派生,也叫继承
{
internal void FormClicked(object sender, EventArgs e)//事件的处理器
{
this.Text = DateTime.Now.ToString();
}
}
}
例四:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ConsoleApp41
{
class Program
{
static void Main(string[] args)
{
MyForm myForm = new MyForm();//事件的响应者
myForm.ShowDialog();
}
}
class MyForm:Form
{
private TextBox textBox;
private Button button;//事件拥有者
public MyForm()
{
this.textBox = new TextBox();
this.button = new Button();
this.Controls.Add(this.textBox);
this.Controls.Add(this.button);
this.button.Text = "say hello!";
this.button.Top = 100;//非可视化编程,难受啊,马飞
this.button.Click += this.ButtonClicked; //事件click,事件的订阅
}
private void ButtonClicked(object sender, EventArgs e)//事件的处理器
{
this.textBox.Text = "hello,world!";
}
}
}
例五:可视化编程
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//this.button3.Click += new EventHandler(this.ButtonClicked);
this.button3.Click += (object sender, EventArgs e) =>
{
this.textBox1.Text = "hoho";
};//比较流行的挂接事件写法
}
private void ButtonClicked(object sender, EventArgs e)
{
if (sender==this.button1)
{
this.textBox1.Text = "hello!";
}
if (sender==button2)
{
this.textBox1.Text = "world!";
}
if (sender==button3)
{
this.textBox1.Text = "Mr.fucker!";
}
}
}
}
运行结果
·注意
事件处理器是方法成员。
挂接事件处理器的时候,可以使用委托实例,也可以直接使用方法命名,这个是“语法糖”。
事件处理器对事件的订阅不是随意的,匹配与否由声明事件时所使用的委托类型来检测。
事件可以同步调用也可以异步调用