事件概述
什么是事件
namespace DelegateDemo1
{
internal class Program
{
static void Main(string[] args)
{
MusicPlayer mp3 = new MusicPlayer();
mp3.AfterStartedPlay = () =>
{
Console.WriteLine("加载歌词...");
Console.WriteLine("加载背景...");
};
mp3.StartPlay();
mp3.BeforeStopedPlay = () =>
{
Console.WriteLine("删除歌词...");
Console.WriteLine("删除背景...");
};
mp3.StopPlay();
}
}
public class MusicPlayer
{
//做几个事件
//1. 音乐开始播放后触发某个事件
public Action AfterStartedPlay;
//2. 音乐停止播放之前触发某个事件
public Action BeforeStopedPlay;
private void PlayMusic()
{
Console.WriteLine($"开始播放...");
}
/// <summary>
/// 按下【播放】开始播放音乐
/// </summary>
public void StartPlay()
{
PlayMusic();
if (AfterStartedPlay != null)
{
AfterStartedPlay();
}
}
/// <summary>
/// 按下【停止】停止播放音乐
/// </summary>
public void StopPlay()
{
if(BeforeStopedPlay != null)
{
BeforeStopedPlay();
}
Console.WriteLine($"播放结束...");
}
}
}
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 WinFormDelegate
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
userControl_Button1.TripleClick = () =>
{
MessageBox.Show("1");
};
}
}
}
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 WinFormDelegate
{
public partial class UserControl_Button : UserControl
{
public UserControl_Button()
{
InitializeComponent();
}
public Action TripleClick;
int count = 0;
private void button1_Click(object sender, EventArgs e)
{
count++;
if(count >= 3)
{
if(TripleClick != null)
{
TripleClick();
}
count = 0;
}
}
}
}
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 WinFormDelegate
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
userControl_Button1.TripleClick += () =>
{
MessageBox.Show("1");
};
}
}
}
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 WinFormDelegate
{
public partial class UserControl_Button : UserControl
{
public UserControl_Button()
{
InitializeComponent();
}
public event Action TripleClick;
int count = 0;
private void button1_Click(object sender, EventArgs e)
{
count++;
if(count >= 3)
{
if(TripleClick != null)
{
TripleClick();
}
count = 0;
}
}
}
}
事件与委托的区别
- 因为委托是public的,它可以在外界随意调用,而不是只有当事件发生之后才调用;
- 若将委托改为private的,那么它就不可以在外界调用了,但是它也不能在外界给它绑定方法了。
- 委托可以直接使用=赋值,可以将以前注册的方法都覆盖掉 (= null)。
- 因此需要事件。
- 事件是.NET对委托的封装。
- 事件只能使用 += -= 来赋值,而 += -= 不能赋null值
- 事件在外部不能直接调用,事件只能在定义事件的类的内部触发。
- 使用ILSPY看到事件就是一个私有的委托和两个公有的方法。
namespace DelegateDemo1
{
internal class Program
{
static void Main(string[] args)
{
MusicPlayer mp3 = new MusicPlayer();
mp3.AfterStartedPlay = () =>
{
Console.WriteLine("加载歌词...");
Console.WriteLine("加载背景...");
};
mp3.StartPlay();
mp3.BeforeStopedPlay = () =>
{
Console.WriteLine("删除歌词...");
Console.WriteLine("删除背景...");
};
mp3.StopPlay();
}
}
public class MusicPlayer
{
//做几个事件
//1. 音乐开始播放后触发某个事件
public Action AfterStartedPlay;
//2. 音乐停止播放之前触发某个事件
public Action BeforeStopedPlay;
private void PlayMusic()
{
Console.WriteLine($"开始播放...");
}
/// <summary>
/// 按下【播放】开始播放音乐
/// </summary>
public void StartPlay()
{
PlayMusic();
if (AfterStartedPlay != null)
{
AfterStartedPlay();
}
}
/// <summary>
/// 按下【停止】停止播放音乐
/// </summary>
public void StopPlay()
{
if(BeforeStopedPlay != null)
{
BeforeStopedPlay();
}
Console.WriteLine($"播放结束...");
}
}
}
- 事件可以写在接口里面,类实现这个接口之后,就会编译成一个委托加两个方法。
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 WinFormDelegate
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent()
}
private void Form1_Load(object sender, EventArgs e)
{
this.ucLogin1.Login += (object arg1,UserEventArgs eventArgs) =>
{
if(eventArgs.UserName == "admin" && eventArgs.Password == "123")
{
eventArgs.IsLoggedIn = true
}
}
}
}
}
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 WinFormDelegate
{
public partial class UCLogin : UserControl
{
public UCLogin()
{
InitializeComponent()
}
public event Action<object,UserEventArgs> Login
private void Btn_Login_Click(object sender, EventArgs e)
{
if (Login != null)
{
UserEventArgs eventArgs = new UserEventArgs()
eventArgs.UserName = this.Uid.Text
eventArgs.Password = this.Pwd.Text
eventArgs.IsLoggedIn = false
Login(this,eventArgs)
if (eventArgs.IsLoggedIn)
{
this.BackColor = Color.Green
}
else
{
this.BackColor = Color.Red
}
}
}
}
public class UserEventArgs : EventArgs
{
public string UserName
public string Password
public bool IsLoggedIn
}
}
观察者模式
- Subject 被观察者:包含其他对象感兴趣的内容;
- Observer 观察者:当Subject中的某件事发生的时候,会告知Observer,Observer会采取相应的行动。
- 观察者模式
namespace ObserveMode
{
public class Program
{
static void Main(string[] args)
{
HeaterSubject heaterSubject = new HeaterSubject();
heaterSubject.OnBoil += new DisplayObserver().ShowTemperature;
heaterSubject.OnBoil += new AlertObserver().MakeAlert;
heaterSubject.BoilWater();
}
}
public class HeaterSubject
{
private int temperature;
public event Action<int> OnBoil;
public void BoilWater()
{
for(int i = 0; i < 100; i++)
{
temperature = i;
if(temperature > 95)
{
if(OnBoil != null)
{
OnBoil(temperature);
}
}
}
}
}
public class DisplayObserver
{
public void ShowTemperature(int param)
{
Console.WriteLine($"水温 {param} 度");
}
}
public class AlertObserver
{
public void MakeAlert(int param)
{
Console.WriteLine($"水开了,已经{param}度了。");
}
}
}