事件时一个 用户操作 。应用程序需要在事件发生时响应事件。它是在类中声明且生成,且通过同一个类或其他类中的委托与事件处理程序关联。
事件是在发布类中调用的,外部不能调用。发布类就是包含事件的类,订阅类就是接受该事件的类。
我们先定义一个事件类——
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinformControl
{
public class User
{
//定义一个委托
public delegate void UserHandler(object sender, EventArgs e);
public event UserHandler DoSomeThings;//事件,相当于委托实例
public int userID
{
get;
set;
}
public string UserName { get; set; }
private bool isStart { get; set; }
public bool IsStart
{
get { return isStart; }
set
{ isStart = value;
}
}
public void DoSomethings()
{
DoSomeThings?.Invoke(this, new EventArgs());
if (DoSomeThings != null)
{
DoSomeThings.Invoke(this, new EventArgs());
}
}
}
}
在程序里面创建一个窗体来作为事件的订阅者。
private void btn_check_Click(object sender, EventArgs e)
{
User user1 = new User
{
userID = 1,
UserName="黎明"
};
#region 事件
User.UserHandler user = Do_Somethings;
//user += (o, eventargs) =>
//{
//};
this.Invoke(new Action(() =>{
user(user1, new EventArgs());
}));
#endregion
}
private static void Do_Somethings(object sender, EventArgs e)
{
Console.WriteLine("使用中。。。");
//Console.ReadKey();
}
如果要进行多播事件,则可以进行如下操作——
private void btn_check_Click(object sender, EventArgs e)
{
User user1 = new User
{
userID = 1,
UserName="黎明"
};
User.UserHandler user2 = (o, eargs2) =>
{
Console.WriteLine("事件执行完毕");
};
#region 事件
User.UserHandler user = Do_Somethings;
user += (o, eventargs) =>
{
Console.WriteLine("走出来了");
};
user += user2;
this.Invoke(new Action(() =>
{
user(user1, new EventArgs());
}));
#endregion
}
private static void Do_Somethings(object sender, EventArgs e)
{
Console.WriteLine("使用中。。。");
//Console.ReadKey();
}
在发布者那里需要修改以下代码——
public void DoSomethings() { DoSomeThings?.Invoke(this, new EventArgs()); if (DoSomeThings != null) { DoSomeThings.Invoke(this, new EventArgs()); } }
修改为——
public void DoSomethings() { //DoSomeThings?.Invoke(this, new EventArgs()); //if (DoSomeThings != null) //{ // DoSomeThings.Invoke(this, new EventArgs()); //} foreach(UserHandler act in DoSomeThings.GetInvocationList()) { act.Invoke(this, new EventArgs()); } }
DoSomeThings.GetInvocationList()可以用来获取委托列表(事件列表)
如果要自定义一个事件——该事件继承于EventArgs,事件不能够在外部调用,只有在内部:发布者内部,所以可以用一个布尔类型的属性值来调用该方法。自定义事件可以传参数。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinformControl
{
/// <summary>
/// 自定义事件参数
/// </summary>
public class UserArgs : EventArgs
{
public string UserName { get; set; }
public UserArgs(string name)
{
UserName = name;
}
}
}
然后修改User类如下——
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinformControl
{
public class User
{
//定义一个委托
public delegate void UserHandler(object sender, UserArgs e);
public event UserHandler DoSomeThings;//事件,相当于委托实例
public int userID
{
get;
set;
}
public string UserName { get; set; }
private bool isStart { get; set; }
public bool IsStart
{
get { return isStart; }
set
{ isStart = value;
DoSomethings();
}
}
public void DoSomethings()
{
//DoSomeThings?.Invoke(this, new EventArgs());
//if (DoSomeThings != null)
//{
// DoSomeThings.Invoke(this, new EventArgs());
//}
if (isStart)
{
foreach (UserHandler act in DoSomeThings.GetInvocationList())
{
act.Invoke(this, new UserArgs(UserName));
}
}
}
}
}
主窗体的函数如下——
private void btn_check_Click(object sender, EventArgs e)
{
User user1 = new User
{
userID = 1,
UserName="黎明"
};
user1.DoSomeThings += Do_Somethings;
User.UserHandler user2 = (o, args2) =>
{
Console.WriteLine($"{user1.UserName}事件执行完毕");
};
user1.DoSomeThings += user2;
user1.IsStart = true;
//this.Invoke(new Action(() =>
//{
// user1()
//}));
#region 事件
//User.UserHandler user = Do_Somethings;
//user += (o, eventargs) =>
//{
// Console.WriteLine("走出来了");
//};
//user += user2;
//this.Invoke(new Action(() =>
//{
// user(user1, new EventArgs());
//}));
#endregion
}
private static void Do_Somethings(object sender, UserArgs e)
{
Console.WriteLine($"{e.UserName}使用中。。。");
//Console.ReadKey();
}
总结:事件就是和委托相似的一个东西,事件只能够在定义事件的类的内部调用,如果要使用的话,需要用委托来绑定该事件,或者是通过定义这个事件的类的某个属性值来作为判断依据去调用该事件。