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里是对委托变量的操作,可以说事件是对委托的一种封装,也是特殊的委托。

posted on 2017-01-14 12:17  奔游浪子  阅读(121)  评论(0)    收藏  举报

导航