事件拥有者通过内部逻辑触发事件
用户按下按钮执行操作,看似是用户的外部操作引起按钮的 Click 事件触发,实际不然,详细情况大致如下:
- 当用户点击图形界面的按钮时,实际是用户的鼠标向计算机硬件发送了一个电信号。Windows 检测到该电信号后,就查看一下鼠标当前在屏幕上的位置。当 Windows 发现鼠标位置处有个按钮,且包含该按钮的窗口处于激活状态,它就通知该按钮,用户按下了,然后按钮的内部逻辑开始执行
- 典型的逻辑是按钮快速地把自己绘制一遍,绘制成自己被按下的样子,然后记录当前的状态为被按下了。紧接着如果用户松开了鼠标,Windows 就把消息传递给按钮,按钮内部逻辑又开始执行,把自己绘制成弹起的状态,记录当前的状态为未被按下
- 按钮内部逻辑检测到,按钮被执行了连续的按下、松开动作,即按钮被点击了。按钮马上使用自己的 Click 事件通知外界,自己被点击了。如果有别的对象订阅了该按钮的 Click 事件,这些事件的订阅者就开始工作
简言之:用户操作通过 Windows 调用了按钮的内部逻辑,最终还是按钮的内部逻辑触发了 Click 事件。
事件示例
Timer 的一些成员,其中闪电符号标识的两个就是事件:
通过查看 Timer 的成员,我们不难发现一个对象最重要的三类成员:
- 属性(小扳手):对象或类当前处于什么状态
- 方法(小方块):它能做什么
- 事件(小闪电):它能在什么情况下通知谁 ```csharp using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Timers; //需要引用新的名称空间
namespace tttlll { class Program { static void Main(string[] args) { // 1.事件拥有者 timer Timer timer = new Timer(); timer.Interval = 1000; //Interval:时间间隔的长短,1000ms,即1s
// 3.事件的响应者 boyBoy boy = new Boy();Girl girl = new Girl();// 2.事件 Elapsed,5.事件订阅 +=(+=后面跟上事件响应者的事件处理器)timer.Elapsed += boy.Action;timer.Elapsed += girl.Action;timer.Start();Console.ReadLine();}}class Boy{//4.事件处理器 自动生成的Action方法internal void Action(object sender, ElapsedEventArgs e){Console.WriteLine("Jump!");}}class Girl{internal void Action(object sender, ElapsedEventArgs e){Console.WriteLine("Sing!");}}
}
<a name="w4Rvf"></a>##<a name="7Xnr4"></a>## 几种事件订阅方式<a name="b10f9ede"></a>### ⭐事件拥有者和事件响应者是完全不同的两个对象<br />这种组合方式是 MVC、MVP 等设计模式的雏形。Click 事件与上例的 Elapsed 事件的第二个参数的数据类型不同,即这两个事件的约定是不同的。**也就是说,你不能拿影响 Elapsed 事件的事件处理器去响应 Click 事件 —— 因为遵循的约束不同,所以他们是不通用的。**```csharpusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace tttlll{class Program{static void Main(string[] args){//1.事件拥有者 formForm form = new Form();//3.事件响应者 controllerController controller = new Controller(form);form.ShowDialog();}}class Controller{private Form form;public Controller(Form form){if (form!=null){this.form = form;//2.事件 Click 5.事件订阅 +=this.form.Click += this.FormClicked;}}//4.事件处理器 FormClickedprivate void FormClicked(object sender, EventArgs e){this.form.Text = DateTime.Now.ToString();}}}
⭐⭐事件的拥有者和响应者是同一个对象
该示例中事件的拥有者和响应者都是 from。示例中顺便演示了继承:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace tttlll{class Program{static void Main(string[] args){//1.事件拥有者 3.事件响应者 都是 formMyForm form = new MyForm();//2.事件 Click 5.事件订阅 +=form.Click += form.FormClicked;form.ShowDialog();}}class MyForm : Form{//4.事件处理器 FormClickedinternal 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 tttlll{class Program{static void Main(string[] args){MyForm form = new MyForm();form.ShowDialog();}}//3.事件响应者 MyForm对象class MyForm : Form{private TextBox textBox;//1.事件拥有者 button(button是Form的字段成员)private Button button;public MyForm(){this.textBox = new TextBox();this.button = new Button();this.Controls.Add(this.button);this.Controls.Add(this.textBox);//2.事件 Click 5.事件订阅 +=this.button.Click += this.ButtonClicked;this.button.Text = "Say Hello";this.button.Top = 20;}//4.事件处理器 ButtonClickedprivate void ButtonClicked(object sender, EventArgs e){this.textBox.Text = "Hello,World!";}}}
