C#之事件
接着上一次的“委托”,这次来扯出“事件”是什么鬼
首先呢,来看一个小例子,就是做一个用户控件,单机3次弹出一个对话框。
public partial class ThreeGo : UserControl { public ThreeGo() { InitializeComponent(); } public PaPaPa ppp; int count = 0; private void btnThree_Click(object sender, EventArgs e) { if (ppp != null) { count++; if (count ==3) { ppp(); count = 0; } } } } public delegate void PaPaPa();
注意一下哈:winform里的用户控件,直接拖到窗体里不行的,首先应该先生成一下,然后在直接拖到工具箱里,然后会在工具箱最上部的组件里找到自己的用户控件。
有没有注意到,在这个用户控件里,我把委托居然当做属性来用了,这样做的目的我就可以把方法名直接赋值给该用户控件的属性(也就是那个破委托),这样一来就通了
现在看一下,怎么使用这个用户控件,也就是如何给委托属性赋值。
public partial class Form1 : Form { public Form1() { InitializeComponent(); threeGo1.ppp = SanQiang; threeGo1.ppp += YSanQiang; } private void SanQiang() { MessageBox.Show("啪啪啪,三枪!"); } private void YSanQiang() { MessageBox.Show("啪啪啪,再来三枪!"); } }
现在呢,连续点击三次按钮就会弹出来 "啪啪啪,三枪!"和"啪啪啪,再来三枪!"。
虽然呢,一切看起来都还是那么回事,不过呢,有个问题,如果再添加2个按钮,“消灭委托”,“冒充委托”,那这个程序可就乱了套了。
消灭:无论多少次都没有效果
private void button1_Click(object sender, EventArgs e) { threeGo1.ppp = null; } 冒充:直接弹出对话框了 private void button2_Click(object sender, EventArgs e) { threeGo1.ppp(); }
所以就得想想办法了啊。既然外界可以来小米或者伪造这个委托属性,那好说,我把它置为private就OK了嘛。
public partial class ThreeGo : UserControl { public ThreeGo() { InitializeComponent(); } //public PaPaPa ppp; private PaPaPa ppp; public void AddPapapa(PaPaPa p) { ppp += p; } int count = 0; private void btnThree_Click(object sender, EventArgs e) { if (ppp != null) { count++; if (count ==3) { ppp(); count = 0; } } } } public delegate void PaPaPa();
外界调用的话也得改一下。
public Form1() { InitializeComponent(); //threeGo1.ppp = SanQiang; //threeGo1.ppp += YSanQiang; threeGo1.AddPapapa(SanQiang); threeGo1.AddPapapa(YSanQiang); }
效果一样,但是此时就不会再有任何的意外了。
等等,看起来好麻烦啊,有没有简单一点的呢,当然有了,别忘了微软是最贴心的了,进入正题——事件
public partial class ThreeGo : UserControl { public ThreeGo() { InitializeComponent(); } //public PaPaPa ppp; private PaPaPa ppp; //public void AddPapapa(PaPaPa p) //{ // ppp += p; //} public event PaPaPa pa { add { ppp += value; } remove { ppp -= value; } } int count = 0; private void btnThree_Click(object sender, EventArgs e) { if (ppp != null) { count++; if (count == 3) { ppp(); count = 0; } } } } public delegate void PaPaPa();
public partial class Form1 : Form { public Form1() { InitializeComponent(); //threeGo1.ppp = SanQiang; //threeGo1.ppp += YSanQiang; //threeGo1.AddPapapa(SanQiang); //threeGo1.AddPapapa(YSanQiang); threeGo1.pa += SanQiang; threeGo1.pa += YSanQiang; threeGo1.pa -= SanQiang; threeGo1.pa += new PaPaPa(ZSanQinag);//这块也要注意哈,顺道就把委托的实例化给说了,哈哈 } private void ZSanQinag() { MessageBox.Show("啪啪啪,再来三枪!"); } private void SanQiang() { MessageBox.Show("啪啪啪,三枪!"); } private void YSanQiang() { MessageBox.Show("啪啪啪,又来三枪!"); } }
程序效果照旧,而且极其安全,事件只允许+=,-=,永远不会,所以就杜绝了“消灭委托”,而委托的属性是private,所以也不可能假冒伪造,真方便啊!哈哈哈!
现在看一下平时的事件写法吧
public partial class ThreeGo : UserControl { public ThreeGo() { InitializeComponent(); } public event PaPaPa pa; int count = 0; private void btnThree_Click(object sender, EventArgs e) { if (pa != null) { count++; if (count == 3) { pa(); count = 0; } } } } public delegate void PaPaPa();
现在对委托和事件做点总结吧
委托是一种类型,而事件却是一个对象。
事件的add和remove里是对委托变量的操作,可以说事件是对委托的一种封装,也是特殊的委托。
浙公网安备 33010602011771号