六章 委托事件
1委托
是一种数据类型,像类一样
//c#中基本的数据类型都可以作为参数进行传递
//把方法名作为参数进行传递,称为委托
//1
public delegate void SayDele();//声明Say()方法的委托类型,使Say()可以作为参数传递
class Program
{
static void Main(string[] args)
{
//要想传递方法,必须给被传递方法 声明一个委托类型
//1 用Say()方法作为参数传入Show()
Show(Say);
Console.ReadKey();
}
private static void Say()
{
}
private static void Show(SayDele dele)
{
}
}
//2
public delegate int AddDelegate(int num1,int num2);
class Program
{
static void Main(string[] args)
{
//2
int ret = Test(Add);
Console.WriteLine(ret);
Console.ReadKey();
}
private static int Add(int n1, int n2)
{
return n1 + n2;
}
private static int Test(AddDelegate add)
{
int result = add(2, 4);
return result;
}
2节
委托两个小案例
//被声明了委托类型的函数可以作为参数---------------------------------------------------(*)
public delegate string MyDelegate(string mdl);
//字符串数组内容改变
//传一个数组,遍历每一项,执行一个委托函数,去获得执行函数之后的项
class Program
{
static void Main(string[] args)
{
//2、两个小案例
//用委托方法对元素进行某种处理
string[] strs = { "东邪", "西毒", "南帝", "北丐" };
ChangeStrs cs = new ChangeStrs();
string[] lastStrs = cs.GetStrsByChangeStrs(strs, GetStrWithStars); //被申明为委托类型的函数作为参数
//遍历输出结果
foreach(string ls in lastStrs)
{
Console.WriteLine(ls);
}
Console.ReadKey();
}
//对字符数组中每个元素进行处理的函数
private static string GetStr(string str)
{
return "=====" + str + "=====";
}
private static string GetStrWithStars(string str)
{
return "★★★★" + str + "★★★★";
}
}
public delegate string MyDelegate(string mdl);
class ChangeStrs
{
public string[] GetStrsByChangeStrs(string[] strs,MyDelegate mdl)
{
for (int i = 0; i < strs.Length;i++ )
{
//字符串数组中的每一项,都用GetStr()这个被传函数来进行处理,所以需要申明这个函数的委托
strs[i] = mdl(strs[i]);
}
return strs;
}
}
3节
匿名方法和多播委托-----------------------------------------------------------------------------------(*)
//匿名方法
public delegate void MyDelegate();
public delegate void MyDelegate1(int n);
public delegate int MyDelegate2(int n1,int n2);
public delegate string MyDelegate4(string s);
MyDelegate mdl = delegate() { Console.WriteLine("无参数的匿名委托"); };
mdl();
MyDelegate1 mdl1 = delegate(int num) { Console.WriteLine("带参数的匿名委托:" + num); };
mdl1(10);
MyDelegate2 mdl2 = (num1, num2) => { return num1 + num2; }; //拉姆达表达式
int num3 = mdl2(11, 22);
Console.WriteLine("具有拉姆达表达式,带两个参数的委托类型的函数的值:" + num3);
MyDelegate4 mdl4 = (str) => { return str + ",你好帅啊!"; };
string str1 = mdl4("哥哥");
Console.WriteLine(str1);
//多播委托
//调用一个委托类型的委托方法,就可以通过"+" "-"调用其他委托方法----(输出是累积的,返回却只返回最后一个)
//1
//MyDelegate md1 = new MyDelegate(T1);
//相当于下面
MyDelegate mdl = T1;
mdl += T2;
mdl += T3;
mdl -= T2;
mdl();
private static void T1()
{
Console.WriteLine("第一波");
}
private static void T2()
{
Console.WriteLine("第二波");
}
...
//2
//MyDelegate mdl = new MyDelegate(R1);
//int r = mdl();
//Console.WriteLine(r);
//相当于
MyDelegate mdl = R1;
mdl += R2;
mdl += R3;
mdl += R4;
mdl -= R2;
int r = mdl();
Console.WriteLine(r);
private static int R1()
{
return 1;
}
private static int R2()
{
return 2;
}
...
GetInvocationList();//返回一个Delegate[]类型,Delegate是一个抽象类,是所有委托的父类
//传Delegate[]类型
public delegate string MyDelegate();
class Program
{
static void Main(string[] args)
{
Action(Say, Eat, MadeLove);
Console.ReadKey();
}
private static void Action(params MyDelegate[] mdls)
{
foreach(MyDelegate mdl in mdls)
{
string str = mdl();
Console.WriteLine(str);
}
}
private static string Say()
{
return "说";
}
private static string Eat()
{
return "吃";
}
private static string MadeLove()
{
return "爱";
}
4节
窗体传值----------------------------------------------------------------------------(*)
事件的本质就是通过委托实现的
把F1窗口的方法通过委托类型传到F2窗口,使F2窗口可以调用这个f1中方法,操纵f1窗口
//F1
/// 传下去
private void btn1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(txt1.Text,SetText); //给窗口2另外创建一个可以传参数的构造函数
f2.Show();
}
/// f1中需要一个方法给自己赋值,同时这个方法需要传给f2,使f2可以调用这个方法
private void SetText(string content)
{
txt1.Text = content;
}
//F2
public delegate void MyDelegate(string s);
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private MyDelegate _mdl;
public Form2(string content,MyDelegate mdl):this() //接收f1传的方法需要这个方法的委托类型 //:this() 必须要继承实例化窗口的构造函数
{
txt2.Text = content;
//需要把这个委托类型的方法mdl,存入委托类型字段中,使得其他动作可以调用这个委托方法
this._mdl = mdl;
}
/// 滚回去
private void btn2_Click(object sender, EventArgs e)
{
//要使点击"滚回去",把f2值传回f1去,需要f1中有一个给自己窗口赋值的方法
//这个f1方法需要传给f2,使f2可以调用操作这个方法给f1赋值,而f1中的方法传给f2,需要委托类型
if (this._mdl != null) //如果当前窗口的这个委托方法不为Null(存在),才调用这个方法
{
this._mdl(txt2.Text);//调用委托类型字段,就是委托类型方法,就是f1窗口的设置方法
this.Close();
}
}
}
5节
事件总结
//三连击(用户控件)
//委托
public delegate void MyDelegate();
public partial class UserThreeClick : UserControl
{
public UserThreeClick()
{
InitializeComponent();
}
//用户三连击
public MyDelegate _mdl;
int i = 0;
private void btnThreeClick_Click(object sender, EventArgs e)
{
i++;
if(i==3)
{
i = 0;
//MessageBox.Show("太疯狂了");
//设置为委托方法,需要委托类型
if(this._mdl!=null)
{
this._mdl();
}
}
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//窗口加载,传三连击委托类型的委托方法
private void Form1_Load(object sender, EventArgs e)
{
userThreeClick1._mdl = Show;
}
private void Show()
{
MessageBox.Show("找我干嘛");
}
//我是神
private void btnGod_Click(object sender, EventArgs e)
{
userThreeClick1._mdl();
}
}
//通过委托实现这个"三连击"不是很安全了,因为它能够随意的调用
//事件 @注册事件之后的值不能随便改变
public event MyDelegate _mdl; //委托类型的方法变量,加上event就是注册委托类型的事件
委托 = += -=
@事件调用只能用 += -=
userThreeClick1._mdl+=new MyDelegate(userThreeClick1_mdl);
void userThreeClick1__mdl()
{
MessageBox.Show("本人就是这么屌");
}
6节
事件窗口传值
//1 通过自己声明的委托类型MyDelegate的事件传值-----------------------------------------------------------------------(*)
public delegate void MyDelegate(string name);//声明一个委托类型
private event MyDelegate mdl;//声明一个自定义委托类型的事件
//通过事件传值,需要注册事件,先需要委托类型
this.mdl += new MyDelegate(f2.SetText);//注册事件
if(this.mdl!=null)
{
this.mdl(txt1.Text);
f2.Show();
}
public void SetText(string name) //注册事件的委托类型方法传的值必须接受
{
txt2.Text = name;
}
//2 通过系统内置的委托类型EventHandler的事件传值
private event EventHandler evt;//声明一个事件,EventHandler是系统内置的委托类型,它带有2个参数,一个是传控件,一个是传事件类对象
//通过委托事件传值
Form2 f2 = new Form2();
this.evt += new EventHandler(f2.SetText);//注册事件,本质就是一个委托类型的方法
MyEventArgs mea=new MyEventArgs();
mea.Name=txt1.Text;
if(this.evt!=null)
{
this.evt(this, mea);
f2.Show();
}
public void SetText(object sender, EventArgs e) //注册事件,实际就是一个委托类型的方法,与Eventhandler委托类型的参数必须一致
{
MyEventArgs mea = e as MyEventArgs;
txt2.Text = mea.Name;
}
class MyEventArgs : EventArgs{...}