参考:C#语言入门详解 https://www.bilibili.com/video/BV1wx411K7rb?p=19 刘猛铁
评论区笔记:https://www.yuque.com/yuejiangliu/dotnet/timothy-csharp-020-022
事件的五个组成部分:
- 事件的拥有者, (event source,对象)
- 事件成员,(event,成员)
- 事件的响应者,(event subscriber,对象)
- 事件处理器,(event handler,成员)
- 事件订阅,(把事件处理器和事件关联到一起,本质上是一种以委托类型为基础的约定)
timer的事件示例
Timer 的一些成员,其中闪电符号标识的两个就是事件:
通过查看 Timer 的成员,我们不难发现一个对象最重要的三类成员:
-
属性(小扳手):对象或类当前处于什么状态
-
方法(小方块):它能做什么
-
事件(小闪电):它能在什么情况下通知谁
using System;
using System.Timers;
namespace EventExample
{
class Program
{
static void Main(string[] args)
{
// 1.事件拥有者 timer
Timer timer = new Timer();
timer.Interval = 1000; // 时间间隔1000ms
// 3.事件的响应者 boy
Boy boy = new Boy();
Girl girl = new Girl();
// 2.事件成员 Elapsed,5.事件订阅 +=
timer.Elapsed += boy.Action;
timer.Elapsed += girl.Action;
timer.Start();
Console.ReadLine();
}
}
class Boy
{
// 这是通过 VS 自动生成的事件处理器,适合新手上手。
// 4.事件处理器 Action
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Jump!");
}
}
class Girl
{
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Sing!");
}
}
}
几种事件订阅方式
⭐事件拥有者和事件响应者是完全不同的两个对象
这种组合方式是 MVC、MVP 等设计模式的雏形。
Click 事件与上例的 Elapsed 事件的第二个参数的数据类型不同,即这两个事件的约定是不同的。
也就是说,你不能拿影响 Elapsed 事件的事件处理器去响应 Click 事件 —— 因为遵循的约束不同,所以他们是不通用的。
using System;
using System.Windows.Forms;
namespace EventExample
{
class Program
{
static void Main(string[] args)
{
// 1.事件拥有者
var form = new Form();
// 3.事件响应者
var 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.事件处理器
private void FormClicked(object sender, EventArgs e)
{
this.form.Text = DateTime.Now.ToString();
}
}
}
⭐⭐事件的拥有者和响应者是同一个对象
一个对象拿着自己的方法去订阅和处理自己的事件。
using System;
using System.Windows.Forms;
namespace EventExample
{
class Program
{
static void Main(string[] args)
{
// 1.事件拥有者 3.事件响应者 都是 from
var form = new MyForm();
// 2.事件成员 Click 5.事件订阅 +=
form.Click += form.FormClicked;
form.ShowDialog();
}
}
// 因为无法直接修改 Form 类,所以创建了继承与 Form 类的 MyForm 类
class MyForm : Form
{
// 4.事件处理器
internal void FormClicked(object sender, EventArgs e)
{
this.Text = DateTime.Now.ToString();
}
}
}
⭐⭐⭐事件的拥有者是事件响应者的一个字段成员
这种是用得最广的:
using System;
using System.Windows.Forms;
namespace EventExample
{
class Program
{
static void Main(string[] args)
{
// 3.事件响应者 form
var form = new MyForm();
form.ShowDialog();
}
}
class MyForm : Form
{
private TextBox textBox;
// 1.事件拥有者 button
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;
}
// 4.事件处理器
private void ButtonClicked(object sender, EventArgs e)
{
this.textBox.Text = "Hello, World!!!!";
}
}
}
WPF 事件绑定示例
WPF 可以在 XAML 里面绑定事件。
<StackPanel>
<TextBox
x:Name="textBox"
BorderBrush="Black"
Margin="5"/>
<Button
x:Name="button"
Content="Start"
Margin="5"
Width="60"
Height="30"
Click="button_Click"/>
</StackPanel>
它将自动创建事件处理器。
namespace EventExample4
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
textBox.Text += "Hello World!!";
}
}
}
也可以在C#代码中绑定事件
namespace EventExample4
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.button.Click += button_Click; // 事件订阅
}
private void button_Click(object sender, RoutedEventArgs e)
{
textBox.Text += "Hello World!!";
}
}
}