C# 实例解析事件委托之EventHandler

概述

     事件属于委托的一个子集,像我们平时界面上的鼠标点击按钮后响应事件、事件的发布和订阅等都需要用到委托.通过委托可以很好的实现类之间的解耦好。事件委托EventHandler的函数原型如下:delegate 表示这个个委托,事件委托没有返回值,有两个入参,sender是事件触发的对象,e是一个泛型的事件类型参数.

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

用法举例

用法举例1:窗体关闭事件

 public void Cancel(object obj, bool e)        {            if (e)            {                sw.AppendLine("try clsoe window");            }            else            {                sw.AppendLine("clsoe window is cancel");            }        }
   //事件委托1,事件是委托的子集            EventHandler<bool> windowTryClose = Cancel;            windowTryClose(this, false);

这里在定义了一个委托EventHandler<bool>,将方法Cancel委托给他,然后嗲用委托执行。

注意:EventHandler<bool> windowTryClose = Cancel;是EventHandler<bool> windowTryClose = new EventHandler<bool>(Cancel);的简写

传入的参数是false,所以运行结果:

clsoe window is cancel

用法举例2 :按钮点击事件

  //事件委托2            Button button = new Button();            button.ClickEvent += Button_Click;            button.ClickAction();
  public void Button_Click(Object sender, EventArgs args)        {            sw.AppendLine("这是按钮点击事件");        }
  public class Button    {        public EventHandler ClickEvent;        public void ClickAction()        {            ClickEvent.Invoke(this, new EventArgs());        }    }

这里主要是写了按钮点击事件的一个委托,一般在定义事件委托时前面可以用event去修饰,我这里省略了,

用法举例3 :事件发布与订阅

  //事件委托3            var myPublishEventArgs = new PublishEvent();            _ = new SubscribeEvent(myPublishEventArgs);            myPublishEventArgs.Publish();
 public class MyPublishEventArgs : EventArgs    {        public string InfoString { get; set; }    }
    public class PublishEvent    {        public event EventHandler<MyPublishEventArgs> OnPublish;        public void Publish()        {            OnPublish?.Invoke(this, new MyPublishEventArgs() { InfoString = "hello" });        }    }
    public class SubscribeEvent    {        public SubscribeEvent(PublishEvent publishEvent)        {            publishEvent.OnPublish += Subscribe;        }        public void Subscribe(Object sender, MyPublishEventArgs args)        {            MessageBox.Show($"我接收到的消息是:{args.InfoString}");        }    }

这里封装了几个类,MyPublishEventArgs是我要发送的事件,MyPublishEventArgs这个类是发布者,SubscribeEvent这个是订阅者,主要订阅事件一定要放在发布前,这样才能成功接收到事件.

委托部分这里就讲解完事了,全部源码如下:

using PropertyChanged;using System;using System.Text;using System.Threading;using System.Windows;
namespace Caliburn.Micro.Hello.ViewModels{    [AddINotifyPropertyChangedInterface]    public class DelegateViewModel : Screen,IViewModel    {        public string ResultString { get; set; }        delegate int DelegateM(string a, string b);//声明,可以有返回值也可以没有        StringBuilder sw = new StringBuilder();
        public DelegateViewModel()        {            DisplayName = "DelegateTest";        }
        public void Test()        {            sw.AppendLine($"【Delegate测试】执行线程id:{Thread.CurrentThread.ManagedThreadId}");
            //func用法1            //Func<string, string, int> func = new Func<string, string, int>(p.StringAddA);            Func<string, string, int> func = StringAddA;//简写            var result = func.Invoke("3", "5");//可以简化为func("3", "5")            sw.AppendLine($"【func用法1】func返回结果是:{result}");
            //func用法2,用lamda表达式简化写法,通过+=注册实现多播委托            func += (a, b) =>            {                return int.Parse(a) - int.Parse(b);            };            sw.AppendLine($"【func用法2】func返回结果是:{func("3", "5")}");
            //Action用法            //Action<string, string> action = new Action<string, string>(p.StringAddB);            Action<string, string> action = StringAddB;//简写            IAsyncResult asyncResult = action.BeginInvoke("3", "5", null, null);//action("3", "5"),BeginInvoke异步执行,即:开启新现成处理StringAddB            action.EndInvoke(asyncResult);//阻塞委托,直到执行完成            if (asyncResult.IsCompleted)            {                sw.AppendLine($"【Action用法】当前异步委托线程已执行完成");            }
            Test(func, action);//将方法委托后转化为参数进行传递
            //delegate用法            //DelegateM delegateM = new DelegateM(p.StringAddA);            DelegateM delegateM = StringAddA;//简写            sw.AppendLine($"【delegate用法】delegate返回结果是:{delegateM("3", "5")}");
            //事件委托1,事件是委托的子集            EventHandler<bool> windowTryClose = new EventHandler<bool>(Cancel);            windowTryClose(this, false);
            //事件委托2            Button button = new Button();            button.ClickEvent += Button_Click;            button.ClickAction();
            //事件委托3            var myPublishEventArgs = new PublishEvent();            _ = new SubscribeEvent(myPublishEventArgs);            myPublishEventArgs.Publish();
            ResultString = sw.ToString();        }
        public int StringAddA(string a, string b)        {            return int.Parse(a) + int.Parse(b);        }
        public void StringAddB(string a, string b)        {            sw.AppendLine($"【Action用法】Action执行线程id:{Thread.CurrentThread.ManagedThreadId}");            sw.AppendLine($"【Action用法】Action执行结果:{(int.Parse(a) + int.Parse(b))}");        }
        public void Test(Func<string, string, int> f, Action<string, string> a)        {            a.Invoke(f.Invoke("3", "5").ToString(), "5");        }
        public void Cancel(object obj, bool e)        {            if (e)            {                sw.AppendLine("try clsoe window");            }            else            {                sw.AppendLine("clsoe window is cancel");            }        }
        public void Button_Click(Object sender, EventArgs args)        {            sw.AppendLine("这是按钮点击事件");        }
        public void MyEvent(Object sender, EventArgs args)        {            sw.AppendLine("这是按钮点击事件");        }    }
    public class Button    {        public EventHandler ClickEvent;        public void ClickAction()        {            ClickEvent.Invoke(this, new EventArgs());        }    }
    public class MyPublishEventArgs : EventArgs    {        public string InfoString { get; set; }    }
    public class PublishEvent    {        public event EventHandler<MyPublishEventArgs> OnPublish;        public void Publish()        {            OnPublish?.Invoke(this, new MyPublishEventArgs() { InfoString = "hello" });        }    }
    public class SubscribeEvent    {        public SubscribeEvent(PublishEvent publishEvent)        {            publishEvent.OnPublish += Subscribe;        }        public void Subscribe(Object sender, MyPublishEventArgs args)        {            MessageBox.Show($"我接收到的消息是:{args.InfoString}");        }    }}

运行结果:

C# 实例解析事件委托之EventHandler