近期和几位做嵌入式开发的朋友闲聊过程中,一位朋友抱怨到:这C#太难用了,我想在N个窗体(或者是N个用户组件之间)传递值都搞不定,非得要定义一个全局变量来存储,然后用定时器来刷新值,太Low了。我急切的回答道:这很简单,不就是委托的事嘛。那你来一个示例啊:朋友道。此为这篇博客的起因,所以此篇博客对于有c#开发经验的伙伴们那是小菜一喋。

一、对委托的理解

     委托:同一个功能,可以根据不同的场景委托给不同的方法具体执行; 举个栗子:某位美食爱好妹子,通常自己做美食;找到男票后,就男票做美食;换男票后,就第二任男票做美食。我们把这例子委托抽象化:

    定义一个委托功能:做美食;规范及流程:输入”食材“,通过”做美食“的委托,输出”美食“。

    委托实现之自己做:妹子自己做美食

    委托实现之一号男票做:一号男票做美食

    委托实现之二号男票做:二号男票做美食

    做美食这项功能,被妹子在不同的时间段分配给了不同的对象,虽然妹子,男一,男二做的美食都很好吃,但味道肯定有区别。这就是委托生活化的示例,各位看观了解否(偷笑)。

二、代码实现

    上面的示例如何用代码实现,这里就不展示了(真的很简单)。下面我们换一个稍有难度和实际应用的示例,需求说明:主窗体显示一个列表,子窗体增加数据(不关闭子窗体的情况下),主窗体列表自动更新,且第二个子窗体打开后,窗体内的列表也要同时更新。

    UI设计:一个主窗体,两个子窗体(A窗体:增加数据,B窗体:显示数据),一个用户组件(列表显示内容)

2.1 EventBus实现

代码如下:

复制代码
public class EventBus<T>     {         private List<T> list = new List<T>();          public event EventHandler<EventBusArg<List<T>>> EventNotice;         public delegate void DelegateItemInfoEvent(List<T> items);          public void Add(T item)         {             this.list.Add(item);             this.TriggerEventNotice();         }          public void Remove(T item)         {             this.list.Remove(item);             this.TriggerEventNotice();         }          public List<T> GetAll()         {             return this.list;         }          private void TriggerEventNotice()         {             if (this.EventNotice != null)             {                 this.EventNotice.Invoke(this, new EventBusArg<List<T>>()                 {                     Data = this.GetAll()                 });             }         }     }      public class EventBusArg<T> : EventArgs     {         public T Data { get; set; }     }
复制代码

重点:

1. 定义了一个委托类型:DelegateItemInfoEvent(List<T> items)

2. 定义了一个事件对象:EventHandler<EventBusArg<List<T>>>

3. 事件对象的参数必须继承EventArgs对象

4. 事件依赖委托

2.2 主窗体

代码如下:

 

复制代码
        private EventBus<ItemInfo> eventBus = new EventBus<ItemInfo>();         private EventBus<ItemInfo>.DelegateItemInfoEvent FunItem;         public Form1()         {             InitializeComponent();             this.eventBus.EventNotice += EventBus_EventNotice;         }          private void EventBus_EventNotice(object sender, EventBusArg<List<ItemInfo>> e)         {             if (this.ucList1.InvokeRequired)             {                 FunItem = new EventBus<ItemInfo>.DelegateItemInfoEvent(RefreshItem);                 this.ucList1.Invoke(FunItem, e.Data);             }             else             {