千家信息网

C#消息事件封装

发表于:2025-02-03 作者:千家信息网编辑
千家信息网最后更新 2025年02月03日,本人一直认为AS3的事件处理机制很是给力 , 今天鼓捣了出来并完美得通过了测试。在AS3中使用函数addEventListener添加事件侦听,用removeEventListener移除事件侦听。着
千家信息网最后更新 2025年02月03日C#消息事件封装

本人一直认为AS3的事件处理机制很是给力 , 今天鼓捣了出来并完美得通过了测试。在AS3中使用函数addEventListener添加事件侦听,用removeEventListener移除事件侦听。着用封装的一个类库可以彻底地终结消息传递中无规则,无规律的混乱状态,从而达到代码逻辑清晰性。改起来也相当简单(做过程序员的都懂)。

关于此类库的实现原理 , 其实使用的是委托(delegate),让侦听函数(观察者)挂载到此委托上,当然消息有不同的类型,如windows系统中有单击,双击,右击等不同的事件类型,在这个类库里面都有实现。

首先,需要指出:

IEventType ( 所有事件类型的接口 )

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MsgEventLib.com{    public interface IEventType    {        ///         /// 类的类型        ///         Type EventMainType { get; }        String GetEventTypeName(string type);    }}

思想:事件类型以 类的Type.Name + "_" + 事件名称 。 以GetEventTypeName方法实现。

传递的消息体:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MsgEventLib.com{    public class BaseEvent    {        public BaseEvent(string eventType, object sender, object msg)        {            this.eventType = eventType;            this.sender = sender;            this.msg = msg;        }        private string @eventType;        public string EventType        {            set { this.eventType = value; }            get { return this.eventType; }        }        private object @sender;        public Object Sender         {            set { this.sender = value; }            get { return this.sender; }        }        private object @msg;        public object Msg        {            set { this.msg = value; }            get { return this.msg; }        }    }}

其中:eventType为事件类型名称 GetEventTypeName , Sender为发送者 , Msg为消息体


事件侦听管理器的实现

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MsgEventLib.com{    public sealed class EventListener : IEventListener    {        private static IEventListener @instance;        public static IEventListener Instance        {            get {                if (instance == null) instance = new EventListener();                return instance;            }        }        private Dictionary @listeners;        private EventListener()        {            @listeners = new Dictionary();        }        public void AddEventListener(string type, DeListener myListener)        {            if (!@listeners.ContainsKey(type))                @listeners.Add(type, myListener);            else                @listeners[type] += myListener;        }        public void RemoveEventListener(string type, DeListener myListener)        {            if (@listeners.ContainsKey(type))            {                @listeners[type] -= myListener;                if (@listeners[type] == null)                    @listeners.Remove(type);            }        }        public void RemoveAllEventListener()        {            if (@listeners != null && @listeners.Count > 0)            {                List keys = new List(@listeners.Keys);//获得所有的键值                for (int j = 0; j < keys.Count; j++)                {                    if (@listeners[keys[j]] != null)                    {                        Delegate[] des = @listeners[keys[j]].GetInvocationList();                        if (des != null && des.Length > 0)                        {                            for (int i = 0; i < des.Length; i++)                            {                                @listeners[keys[j]] -= des[i] as DeListener;                            }                        }                    }                    @listeners.Remove(keys[j]);                }            }        }        public DeListener GetDeListenerByType(string type)        {            if (@listeners != null && @listeners.ContainsKey(type))            {                return @listeners[type];            }            return null;        }        public void Destory()        {            this.RemoveAllEventListener();            if (@instance != null) @instance = null;        }    }}

值得注意的是 , 字典 : key为事件类型(GetEventTypeName) , value为委托(可能有多个挂载/观察者)


关于事件发送者(主题)

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MsgEventLib.com{    public sealed class EventDispacterManager : IEventDispacterManager    {        private static IEventDispacterManager @instance;        public static IEventDispacterManager Instance        {            get            {                if (instance == null) instance = new EventDispacterManager();                return instance;            }        }        public void Dispatch(string type , BaseEvent @myevent)        {            DeListener target = EventListener.Instance.GetDeListenerByType(type);            if (target != null)            {                target(@myevent);            }        }    }}

测试的结果

1 , 事件类型

using System;using System.Collections.Generic;using System.Linq;using System.Text;using MsgEventLib.com;namespace TestA.com{    public class MyEventType : IEventType    {        private static MyEventType @instance;        public static MyEventType Instance        {            get {                if (@instance == null) @instance = new MyEventType();                return @instance;            }        }        public Type EventMainType        {            get { return typeof(MyEventType); }        }        public string GetEventTypeName(string type)        {            return this.EventMainType.Name + "_" + type;        }        public static string CLOSE_WINDOWS = "CLOSE_WINDOWS";        public static string OTHRT_TYPE = "OTHRT_TYPE";    }}

2 , 3个类(侦听着)

①:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using MsgEventLib.com;namespace TestA.com{    public sealed class Listeners    {        public Listeners()        {             string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);            EventListener.Instance.AddEventListener(type, this.Li);        }        private void Li(BaseEvent e)        {            Console.WriteLine("Listeners 触发了Event {0} ", e.Msg);        }    }}

②:

using MsgEventLib.com;using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestA.com{    public sealed class Lis2    {        public Lis2()        {            string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);            EventListener.Instance.AddEventListener(type, this.Li);        }        private void Li(BaseEvent e)        {            Console.WriteLine("Lis2 触发了Event {0} ", e.Msg);        }        public void RemoveLis()        {             string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);            EventListener.Instance.RemoveEventListener(type, this.Li);            Console.WriteLine("Lis2 移除了事件侦听!");        }    }}

③:

using MsgEventLib.com;using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestA.com{    public sealed class Lis3    {        public Lis3()        {            string type = MyEventType.Instance.GetEventTypeName(MyEventType.OTHRT_TYPE);            EventListener.Instance.AddEventListener(type, this.Li);        }        private void Li(BaseEvent e)        {            Console.WriteLine("Lis3 触发了Event {0} ", e.Msg);        }    }}

事件发送者

using System;using System.Collections.Generic;using System.Linq;using System.Text;using MsgEventLib.com;namespace TestA.com{    public sealed class Dispatch    {        public void Dis()        {             string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);            EventDispacterManager.Instance.Dispatch(type,                new BaseEvent(type, this, "Event_关闭你的窗口"));        }    }}

测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestA.com;


namespace TestA
{
public class Program
{
static void Main(string[] args)
{
Dispatch di = new Dispatch();
Listeners li = new Listeners();
Lis2 li2 = new Lis2();
Lis3 li3 = new Lis3();
di.Dis();
li2.RemoveLis();
di.Dis();

Console.Read();

}
}
}

结果:

因为Lis3侦听的不是事件CLOSE_WINDOWS , 既不会触发 。 因为Lis2移除了事件,所以第二次不会触发。

这只是部分大码。详细请见附件。

附件:http://down.51cto.com/data/2366478
0