C#超簡單自定義事件


我知道你為啥點進來,所以不要猶豫了,立刻馬上果斷創建控制台項目,直接復制下面精干短小而又強大的代碼運行: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestEvent
{
    class MyEvent //聲明事件
    {
        public event EventHandler<EventArgs> OnInput; //定義一個委托類型的事件  
        public void WaitInput()
        {
            while (true)
            {
                if (Console.ReadLine() == "x")
                    OnInput(this, new EventArgs()); //觸發事件
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyEvent Evt = new MyEvent();//實例化
            Evt.OnInput += On_Input; //綁定事件到方法  
            Evt.WaitInput();
        }
//事件處理方法
private static void On_Input(object sender, EventArgs e) { Console.WriteLine("你觸發了‘X’!"); } } }

輸入'x'回車,看效果:

如果觸發事件的時候,想傳遞點參數怎么辦?看來你是一個要求很高的人!請刪掉上面的代碼,復制下面的進去運行看看:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestEvent
{
    //事件參數定義
    class MyEventArgs : EventArgs
    {
        char _char;
        string _msg;
        //事件參數重載
        public MyEventArgs(char chr)//當輸入內容為字符
        {
            this._char = chr;
        }
        public MyEventArgs(string msg)//當輸入內容為字符串
        {
            this._msg = msg;
        }
        //事件屬性
        public int Ascii//獲取輸入的(首字符)ASCII碼
        {
            get { return string.IsNullOrEmpty(_msg) ? (int)_char : 0; }
        }
        public char Char//獲取輸入的(首)字符
        {
            get { return string.IsNullOrEmpty(_msg) ? _char : '?'; }
        }
        public string Msg//獲取輸入的字符串
        {
            get { return string.IsNullOrEmpty(_msg) ? "Not String!" : _msg; }
        }
    }
    //事件
    class MyEvent
    {
        public event EventHandler<MyEventArgs> OnInput; //定義一個委托類型的事件  
        public void WaitInput()
        {
            while (true)
            {
                string str = Console.ReadLine();
                if (str.Length == 1)
                    OnInput(this, new MyEventArgs(str[0])); //觸發事件
                else
                    OnInput(this, new MyEventArgs(str)); //演示不同的參數類型
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyEvent Evt = new MyEvent();//實例化
            Evt.OnInput += On_Input; //綁定事件,也就是觸發的方法
            Evt.WaitInput();
        }
        //事件處理方法
        private static void On_Input(object sender, MyEventArgs e)
        {
            Console.WriteLine("輸入的內容: " + e.Msg);
            Console.WriteLine("輸入的字符: " + e.Char + " (ASCII: " + e.Ascii.ToString() + ")");
        }
    }
}

 

效果:

然而還有一些道友有着更高更騷的要求,比如使用了很多的類[n],怎么處理事件,怎么判斷事件是哪個類觸發的?請看下面通過第一個示例修改后的代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestEvent
{
    class MyEvent //聲明事件
    {
        public event EventHandler<EventArgs> OnInput; //定義一個委托類型的事件  
        public string MyID { get; set; }
        public void TestInput( string s)
        {
            if(s==MyID)//如果輸入的和自己的ID一樣,就觸發事件
                OnInput(this, new EventArgs()); 
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            MyEvent[] Evt = new MyEvent[9];//聲明
            for (int i = 0; i < Evt.Length; i++)
            {
                Evt[i] = new MyEvent();//實例化
                Evt[i].MyID = (i + 1).ToString();//設置ID1~9
                Evt[i].OnInput += On_Input; //都綁定事件到同一個方法
            }
            while (true)//由於是單線程不能每個都循環,輸入監視放到這里來,寫成多線程代碼增多太繞了
            {
                string s = Console.ReadLine();
                foreach (MyEvent me in Evt)
                    me.TestInput(s);//分別提交測試
            }
        }
        //事件處理方法
        private static void On_Input(object sender, EventArgs e)
        {
            string _id = (sender as MyEvent).MyID;//注意這里
            Console.WriteLine("" + _id + " 被觸發!");
        }
    }
}

輸入數字后回車看效果:

最后還剩一個特別說明,專門為好奇心特別重的朋友准備,上面的代碼中,綁定事件為啥寫成+=?因為...

Evt.OnInput += On_Input; //綁定事件
Evt.OnInput -= On_Input; //解綁事件

6-18:再補充一個簡單的例子,在事件處理中設置參數,決定是否退出監聽輸入:

//事件參數定義
class MyEventArgs : EventArgs
{
    public MyEventArgs(string s) { InputString = s; }
    public string InputString { get; private set; }
    public bool Cancel { get; set; }
}
//事件
class MyEvent
{
    public event EventHandler<MyEventArgs> OnInput; //定義一個委托類型的事件  
    public void WaitInput()
    {
        while (true)//監視輸入的循環
        {
            string str = Console.ReadLine();
            if (!string.IsNullOrEmpty(str))
            {
                MyEventArgs myevent = new MyEventArgs(str);
                OnInput(this, myevent); //觸發事件
                if (myevent.Cancel)
                {
                    Console.WriteLine("退出監聽!");
                    break;
                }
            }
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        
        MyEvent Evt = new MyEvent();    //實例化
        Evt.OnInput += On_Input;        //綁定事件
        Evt.WaitInput();                //監聽輸入
        Evt.OnInput -= On_Input;        //解綁事件
        Console.ReadLine();
    }
    //事件處理方法
    private static void On_Input(object sender, MyEventArgs e)
    {
        if (e.InputString == "x")
            e.Cancel = true; //設置取消監聽
        else
            Console.WriteLine("您輸入了:" + e.InputString);
    }
}

效果:

上面的示例修改自網上,機制、原理啥的我也不復制了,太繞了,反正發一大堆文字也沒啥人願意看,還不如簡單粗暴直接代碼算了。大家都是這么用,無毒無副作用無不良反應。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM