• 委托事件




    六章    委托事件


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

  • 相关阅读:
    HTML if条件注释解读
    Springboot整合logback日志系统
    Springboot @Valid 参数校验
    JDK1.8 版的if else
    Android获取手机定位坐标
    CentOS8安装JDK
    Vue全局配置文件
    git学习
    百度前端面试题—基础
    前端知识网络
  • 原文地址:https://www.cnblogs.com/adolphyang/p/4739013.html
Copyright © 2020-2023  润新知