初步了解
事件是类的成员,属性(存储和访问数据)、方法(加工运算)都是类型的成员。
委托是一种类。
对象O
事件E
对象O拥有一个事件E:当E事件发生的时候,O可以通知别的对象。
事件的功能:使得对象具有通知的能力
用于对象或类之间的动作协调或者信息传递。
订阅:提供代码,当事件发生的时候执行这些代码,被称为事件处理程序。
通过事件发送的消息:EventArgs事件参数
根据消息采取行动:响应事件
事件的功能:通知+事件参数(可选)
MVC、MVP、MVVM模式都是事件模式更加高级的玩法。
日常开发中使用已有事件的机会比较多。
5个要素
闹钟-响-我-起床-我关注着闹钟
5个步骤:
事件:闹钟响
订阅:我
事件发生:闹钟响了
订阅者被通知:我听到
事件处理:我起床
事件的订阅者/接收者/响应者/通知对象都是一回事情
事件信息/消息/数据/参数都是EventArgs,我们统称事件参数
主要用于客户端,这些程序都是事件驱动的程序。
缺陷:涉及到的对象比较多,因此固化下来了MVC、MVP、MVVM等固定的模式。
事件的使用
五个组成部分:
- EventSource事件拥有者:事件作为一个成员,一定需要有一个拥有者
- Event 事件成员
- Event Subscriber 事件响应者
- Event Handler 事件处理器:事件不是主动发生,一定是某个逻辑触发的
- 事件订阅
事件案例1
一个事件可以挂载多个事件处理器。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace ComputingWithCSharp
{
public class Program
{
static void Main(string[] args)
{
Timer timer = new Timer();//事件拥有者
timer.Interval = 1000;//一秒钟
Boy boy = new Boy();//接收者
Girl girl = new Girl();
timer.Elapsed += boy.Action;//Elapsed是事件;+=表示订阅;action是事件处理器
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 ComputingWithCSharp
{
public class Program
{
static void Main(string[] args)
{
Form form = new Form();
Controller controller = new Controller(form);
form.ShowDialog();
Console.ReadLine();
}
}
class Controller
{
private Form form;//事件的拥有者
public Controller(Form form)
{
if (form != null)
{
this.form = form;//前者是字段,后者是传进来的参数
this.form.Click += this.FormClicked;//前者是事件,中间是事件订阅,后面是事件处理器
}
}
private void FormClicked(object sender, EventArgs e)//这个方法是事件处理器
{
this.form.Text = DateTime.Now.ToString();
}
}
}
事件案例3
事件的拥有者和响应者是同一个对象。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ComputingWithCSharp
{
public class Program
{
static void Main(string[] args)
{
MyForm form = new MyForm();//拥有者和响应者
form.Click += form.FormClicked;//事件、订阅、事件处理器
form.ShowDialog();
Console.ReadLine();
}
}
class MyForm : Form//派生
{
internal void FormClicked(object sender, EventArgs e)
{
this.Text = DateTime.Now.ToString();
}
}
}
事件案例4
事件的响应者包含事件的所有者,事件的所有者是响应者的成员。
这种组合模式是最常见的模式。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ComputingWithCSharp
{
public class Program
{
static void Main(string[] args)
{
MyForm form = new MyForm();
form.ShowDialog();
Console.ReadLine();
}
}
class MyForm : Form//派生
{
private TextBox textBox;
private Button button;//事件的拥有者
public MyForm()//响应者
{
this.textBox = new TextBox();
this.button = new Button();
this.Controls.Add(this.button);
this.Controls.Add(this.textBox);
this.button.Click += this.ButtonClicked;//事件、订阅、事件处理器
this.button.Text = "Say Hello";
this.button.Top = 30;
}
private void ButtonClicked(object sender, EventArgs e)//事件处理器
{
this.textBox.Text = "Hello World!!!!!!";
}
}
}
这种方式不是可见即所得的,如果需要对应图像进行编辑,可以创建项目的时候选择Windows Form类型,窗口就会呈现出如下的的界面,我们可以从工具箱选择窗体,并且在右下角的属性编辑器进行编辑。
事件处理器是可以重用的,条件是事件的拥有者约束条件是一致的。
public Form1()
{
//这里有四种事件的挂载方式
this.button3.Click += this.ButtonClicked;//这两种挂载方式都是欧克的
this.button3.Click += new EventHandler(this.ButtonClicked);//这里后面不需要加括号,加括号表示想调用这个方法,这里只是想把方法名作为变量传进来
this.button3.Click += delegate(object sender, EventArgs e)//这是一个匿名函数,已经过时了
{
this.textBox1.Text = "haha";
}
this.button3.Click += (object sender, EventArgs e) => //这种方式是lamda表达式,参数的数据类型也可以不写
{
this.textBox1.Text = "Hoho";
}
}
private void ButtonClicked(object sender, EventArgs e)
{
if(sender == this.button1)
{
this.textBox1.Text = "Hello";
}
if (sender == this.button2)
{
this.textBox1.Text = "World!";
}
}
WPF同样是桌面应用开发,可以结合XAML进行开发。
一个类主要的三种成员:属性、事件、方法