AdolphYang

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理



六章    委托事件


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{...}

posted on 2015-08-18 11:49  AdolphYang  阅读(225)  评论(0编辑  收藏  举报