1、瞭解C#中的預約義事件處理機制編程
在寫代碼前咱們先來熟悉.net框架中和事件有關的類和委託,瞭解C#中預約義事件框架
的處理。ide
EventArgs是包含事件數據的類的基類,用於傳遞事件的細節。函數
EventHandler是一個委託聲明以下工具
public delegate void EventHandler( object sender , EventArgs e )this
注意這裏的參數,前者是一個對象(其實這裏傳遞的是對象的引用,若是是button1spa
的click事件則sender就是button1),後面是包含事件數據的類的基類。.net
下面咱們研究一下Button類看看其中的事件聲明(使用WinCV工具查看),以Clickorm
事件爲例。對象
public event EventHandler Click;
這裏定義了一個EventHandler類型的事件Click
前面的內容都是C#在類庫中已經爲咱們定義好了的。下面咱們來看編程時產生的代
碼。
private void button1_Click(object sender, System.EventArgs e)
{
...
}
這是咱們和button1_click事件所對應的方法。注意方法的參數符合委託中的簽名(
既參數列表)。那咱們怎麼把這個方法和事件聯繫起來呢,請看下面的代碼。
this.button1.Click += new System.EventHandler(this.button1_Click);
把this.button1_Click方法綁定到this.button1.Click事件。
下面咱們研究一下C#事件處理的工做流程,首先系統會在爲咱們建立一個在後臺監
聽事件的對象(若是是button1的事件那麼監聽事件的就是button1),這個對象用來產生
事件,若是有某個用戶事件發生則產生對應的應用程序事件,而後執行訂閱了事件的所
有方法。
2、簡單的自定義事件(1)
首先咱們須要定義一個類來監聽客戶端事件,這裏咱們監聽鍵盤的輸入。
定義一個委託。
public delegate void UserRequest(object sender,EventArgs e);
前面的object用來傳遞事件的發生者,後面的EventArgs用來傳遞事件的細節,如今
暫時沒什麼用處,一會後面的例子中將使用。
下面定義一個此委託類型類型的事件
public event UserRequest On
下面咱們來作一個死循環
public void Run() { bool finished=false; do {
if (Console.ReadLine()=="h") { On
EventArgs()); } }while(!finished); }
此代碼不斷的要求用戶輸入字符,若是輸入的結果是h,則觸發On
事件的觸發者是自己(this),事件細節無(沒有傳遞任何參數的EventArgs實例)。咱們
給這個類取名爲UserInputMonitor。
下面咱們要作的是定義客戶端的類
首先得實例化UserInputMonitor類
UserInputMonitor monitor=new UserInputMonitor();
而後咱們定義一個方法。
private void ShowMessage(object sender,EventArgs e)
{
Console.WriteLine("HaHa!!");
}
最後要作的是把這個方法和事件聯繫起來(訂閱事件),咱們把它寫到庫戶端類的
構造函數裏。
Client(UserInputMonitor m)
{
m.On
//m.On
//注意這種寫法是錯誤的,由於委託是靜態的
}
下面建立客戶端的實例。
new Client(monitor);
對了,別忘了讓monitor開始監聽事件。
monitor.run();
大功告成,代碼以下:
using System;
class UserInputMonitor{
public delegate void UserRequest(object sender,EventArgs e); //定義委託
public event UserRequest On
public void Run()
{
bool finished=false;
do
{ if (Console.ReadLine()=="h")
{
On
}
}while(!finished);
}
}
public class Client{
public static void Main()
{
UserInputMonitor monitor=new UserInputMonitor();
new Client(monitor);
monitor.Run();
}
private void ShowMessage(object sender,EventArgs e)
{
Console.WriteLine("HaHa!!");
}
Client(UserInputMonitor m)
{
m.On
//m.On
的,由於委託是靜態的
}
}
3、進一步研究C#中的預約義事件處理機制
可能你們發如今C#中有些事件和前面的彷佛不太同樣。例如
private void textBox1_KeyPress(object
sender,System.Windows.Forms.KeyPressEventArgs e)
{ this.textBox1.KeyPress+=newSystem.Windows.Forms.KeyPressEventHandler
(this.textBox1_KeyPress);
}
這裏使用了KeyPressEventArgs而不是EventArgs做爲參數。這裏使用了
KeyEventHandler委託,而不是EventHandler委託。
KeyPressEventArgs是EventArgs的派生類,而KeyEventHandler的聲明以下
public delegate void KeyEventHandler( object sender , KeyEventArgs e );
是參數爲KeyEventArgs的委託。那爲何KeyPress事件要這麼作呢,咱們能夠從兩個
類的構造函數來找答案。
public EventArgs();
public KeyPressEventArgs(char keyChar);
這裏的keyData是什麼,是用來傳遞咱們按下了哪一個鍵的,哈。
我在KeyEventArgs中又發現了屬性
public char KeyChar { get; }
進一步證實了個人理論。下面咱們來作一個相似的例子來幫助理解。
4、簡單的自定義事件(2)
拿咱們上面作的例子來改。
咱們也定義一個EventArgs(相似KeyEventArgs)取名MyEventArgs,定義一個構造函
數public MyEventArgs(char keyChar),一樣咱們也設置相應的屬性。代碼以下
using System;
class MyMyEventArgs:EventArgs{
private char keyChar;
public MyMyEventArgs(char keyChar)
{ this.keychar=keychar; }
public char KeyChar
{ get { return keyChar; } }}
由於如今要監聽多個鍵了,咱們得改寫監聽器的類中的do...while部分。改寫委託,改
寫客戶端傳遞的參數。好了最終代碼以下,好累
using System;
class MyEventArgs:EventArgs
{
private char keyChar;
public MyEventArgs(char keyChar)
{ this.keyChar=keyChar; }
public char KeyChar
{ get { return keyChar; } }
}
class UserInputMonitor
{
public delegate void UserRequest(object sender,MyEventArgs e); //定義委託
public event UserRequest On
public void Run()
{ bool finished=false;
do { string inputString= Console.ReadLine();
if (inputString!="")
On
}while(!finished);
}
}
public class Client
{
public static void Main()
{
UserInputMonitor monitor=new UserInputMonitor();
new Client(monitor);
monitor.Run();
}
private void ShowMessage(object sender,MyEventArgs e)
{ Console.WriteLine("捕捉到:{0}",e.KeyChar); }
Client(UserInputMonitor m)
{
m.On
//m.On