概述
? ? ?事件屬于委托的一個子集,像我們平時界面上的鼠標點擊按鈕后響應事件、事件的發布和訂閱等都需要用到委托.通過委托可以很好的實現類之間的解耦好。事件委托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 :按鈕點擊事件
//事件委托2Button 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 :事件發布與訂閱
//事件委托3var 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異步執行,即:開啟新現成處理StringAddBaction.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);//事件委托2Button button = new Button();button.ClickEvent += Button_Click;button.ClickAction();//事件委托3var 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}");}}
}
運行結果: