.net (object sender, EventArgs e) 学习总结
分析.net中的object sender與EventArgs e
http://blog.csdn.net/feihu19851111/article/details/7523118
作者同類文章X.說的通俗一些,就是:
有一個叫做EventHandler 的家伙,他會告訴你(主程序),有一些事情發(fā)生了:這個事情是誰導致的呢
?是某個object類型對象導致的,它用Source或Sender來表示。這個事情是什么事呢?e的內容就是事情
的內容了。
至于Source和Sender,沒有區(qū)別,你想用哪個就用哪個,其實都是一樣的。
所以,我們在程序中的事件處理函數(shù)就是依賴于這個東西實現(xiàn)的:比方說你點了一個按鈕,程序怎么知
道應該用哪個函數(shù)來處理這個動作呢?那么EventHandler 這個家伙會告訴程序:"button1(sender)被點
擊(e)了,請調用對應的處理函數(shù)"。當然這個函數(shù)是誰,這個函數(shù)要做什么,是由你自己寫的。
再深入一層,這個過程實際上就是:你的動作被windows捕獲,windows把這個動作作為系統(tǒng)消息發(fā)送給
程序(可以看message結構),程序從自己的消息隊列中不斷的取出消息,并在消息循環(huán)中尋找對應的處
理方式,這時message結構中的類似于sender和e的東東就起到了引導程序使用正確的處理函數(shù)的作用。
歸根究底,這個sender和e及其一整套的處理方式,只不過是windows消息機制的另外一種表現(xiàn)罷了 ^_^
如果是按鈕button的話,那sender就是那個button,
e是事件參數(shù),在某些事件里,e用處不大,比如在MouseEventArgs的Mouse事件中,可以看到e包括mouse
的坐標值等,以供你的程序使用。
具體的說來,對于系統(tǒng)提供的類的事件,Sender參數(shù)只是簡單地傳遞了指向引發(fā)事件的那個類的實例的
一個引用,而e是EventArgs類型的參數(shù),它包含了事件所攜帶的信息。
至于第二個問題,我不是很明白“我看到在很多事件代碼中那些代碼都是照寫(object sender,
System.EventArgs e),根本就不用改變sender和e,參數(shù)不是應該隨實際情況變化的嗎?”這句話的意
思,比如說一個按鈕控件,當它的單擊事件被引發(fā)時,系統(tǒng)會自動把這個按鈕對象作一個類型強制轉換
然后賦值給Sender,然后傳遞e。之所以都是這個形式是因為大多數(shù)情況下這些簡單的事件不需要傳遞特
殊的信息,您可以看一下KeyPress事件,這個事件就包含一個KeyPressEventArgs,包含了按鍵的信息。
另外需要明確的一個概念就是類似這樣形式的方法:
private void Button_Click(object sender, EventArgs e)
這樣的方法稱為事件處理方法,它類似于C語言中的事件處理函數(shù),它是在運行時由系統(tǒng)調用的,因此它
的參數(shù)不會變化,就好像我們寫方法時的方法名一樣。
一、了解C#中的預定義事件處理機制
在寫代碼前我們先來熟悉.net框架中和事件有關的類和委托,了解C#中預定義事件的處理。
EventArgs是包含事件數(shù)據(jù)的類的基類,用于傳遞事件的細節(jié)。
EventHandler是一個委托聲明如下
public delegate void EventHandler( object sender , EventArgs e )
注意這里的參數(shù),前者是一個對象(其實這里傳遞的是對象的引用,如果是button1的click事件則sender
就是button1),后面是包含事件數(shù)據(jù)的類的基類。
下面我們研究一下Button類看看其中的事件聲明(使用WinCV工具查看),以Click事件為例。
public event EventHandler Click;
這里定義了一個EventHandler類型的事件Click
前面的內容都是C#在類庫中已經為我們定義好了的。下面我們來看編程時產生的代碼。
private void button1_Click(object sender, System.EventArgs e)?? {???? ...? }
這是我們和button1_click事件所對應的方法。注意方法的參數(shù)符合委托中的簽名(既參數(shù)列表)。那我
們怎么把這個方法和事件聯(lián)系起來呢,請看下面的代碼。
this.button1.Click += new System.EventHandler(this.button1_Click);
把this.button1_Click方法綁定到this.button1.Click事件。
下面我們研究一下C#事件處理的工作流程,首先系統(tǒng)會在為我們創(chuàng)建一個在后臺監(jiān)聽事件的對象(如果是
button1的事件那么監(jiān)聽事件的就是button1),這個對象用來產生事件,如果有某個用戶事件發(fā)生則產生
對應的應用程序事件,然后執(zhí)行訂閱了事件 的所有方法。
二、簡單的自定義事件(1)
首先我們需要定義一個類來監(jiān)聽客戶端事件,這里我們監(jiān)聽鍵盤的輸入。
定義一個委托。
public delegate void UserRequest(object sender,EventArgs e);
前面的object用來傳遞事件的發(fā)生者,后面的EventArgs用來傳遞事件的細節(jié),現(xiàn)在暫時沒什么用處,一
會后面的例子中將使用。下面定義一個此委托類型類型的事件
public event UserRequest On UserRequest;?? //下面我們來做一個死循環(huán)?? public void Run()? {?
? bool finished=false;??? do??? {????? if (Console.ReadLine()=="h")????? {?????
OnUserRequest(this,new EventArgs());????? }??? }
while(!finished);? }
此代碼不斷的要求用戶輸入字符,如果輸入的結果是h,則觸發(fā)On UserRequest事件,事件的觸發(fā)者是本
身(this),事件細節(jié)無(沒有傳遞任何參數(shù)的EventArgs實例)。我們給這個類取名為UserInputMonitor
。下面我們要做的是定義客戶端的類。首先得實例化UserInputMonitor類。
UserInputMonitor monitor=new UserInputMonitor();//然后我們定義一個方法。private void
ShowMessage(object sender,EventArgs e){
Console.WriteLine("HaHa!!");}
最后要做的是把這個方法和事件聯(lián)系起來(訂閱事件),我們把它寫到庫戶端類的構造函數(shù)里。
Client(UserInputMonitor m){
m.On UserRequest+=new UserInputMonitor.UserRequest(this.ShowMessage);
//m.OnUserRequest+=new m.UserRequest(this.ShowMessage);
//注意這種寫法是錯誤的,因為委托是靜態(tài)的
}
下面創(chuàng)建客戶端的實例。
new Client(monitor);
對了,別忘了讓monitor開始監(jiān)聽事件。
monitor.run();
大功告成,代碼如下:
using System;
class UserInputMonitor{
public delegate void UserRequest(object sender,EventArgs e);
//定義委托
public event UserRequest OnUserRequest;
//此委托類型類型的事件
public void Run(){
bool finished=false;
do{
if (Console.ReadLine()=="h")
{
OnUserRequest(this,new EventArgs());
}
}
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.OnUserRequest+=new UserInputMonitor.UserRequest(this.ShowMessage);
//m.OnUserRequest+=new m.UserRequest(this.ShowMessage);
//注意這種寫法是錯誤的,因為委托是靜態(tài)的
}
}
三、進一步研究C#中的預定義事件處理機制
可能大家發(fā)現(xiàn)在C#中有些事件和前面的似乎不太一樣。例如
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e){}
this.textBox1.KeyPress+=newSystem.Windows.Forms.KeyPressEventHandler
(this.textBox1_KeyPress);
這里使用了KeyPressEventArgs而不是EventArgs作為參數(shù)。這里使用了KeyEventHandler委托,而不是
EventHandler委托。
KeyPressEventArgs是EventArgs的派生類,而KeyEventHandler的聲明如下
public delegate void KeyEventHandler( object sender , KeyEventArgs e );
是參數(shù)為KeyEventArgs的委托。那為什么KeyPress事件要這么做呢,我們可以從兩個類的構造函數(shù)來找
答案。
public EventArgs();
public KeyPressEventArgs(char keyChar);
這里的keyData是什么,是用來傳遞我們按下了哪個鍵的,哈。
我在KeyEventArgs中又發(fā)現(xiàn)了屬性
public char KeyChar { get; }
進一步證明了我的理論。下面我們來做一個類似的例子來幫助理解。
四、簡單的自定義事件(2)
拿我們上面做的例子來改。
我們也定義一個EventArgs(類似KeyEventArgs)取名MyEventArgs,定義一個構造函數(shù)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;
}
}
}
因為現(xiàn)在要監(jiān)聽多個鍵了,我們得改寫監(jiān)聽器的類中的do...while部分。改寫委托,改寫客戶端傳遞的
參數(shù)。好了最終代碼如下,好累。
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 OnUserRequest;
//此委托類型類型的事件
public void Run(){
bool finished=false;
do{
string inputString= Console.ReadLine();
if (inputString!="")
OnUserRequest(this,new MyEventArgs(inputString[0]));
}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.OnUserRequest+=new UserInputMonitor.UserRequest(this.ShowMessage);
//m.OnUserRequest+=new m.UserRequest(this.ShowMessage);
//注意這種寫法是錯誤的,因為委托是靜態(tài)的
}
}
========
(object sender, EventArgs e)中的sender 和e有什么用
?
(object sender, EventArgs e)中的sender 和e有什么用呀?請寫段代碼解釋一下它們的作用,最好詳
細的解釋一下,謝謝各位了!我學的是GUI中的winform e有什么用法呀?“就是你點擊的button.可以通
過類型轉換得到這個button的引用”那sender 在其中扮演什么作用?
?在你的窗體中添加一個Label,雙擊Label的MouseClick事件。添加如下方法:
private void label1_MouseClick(object sender, MouseEventArgs e)??????? {??????????? Label
senderLabel = (Label)sender;//根據(jù)sender引用控件。
??? senderLabel.Text = e.Button.ToString();//根據(jù)e中的Button參數(shù),判斷是左鍵還是右鍵。?????
? }
然后在窗體中單擊你的Label,就會顯示你單擊的鼠標的按鍵Rigle或者Left。
——————————————————
以Button為例:
protected void Button1_Click(object sender, EventArgs e)
其中的sender,就是你點擊的button.可以通過類型轉換得到這個button的引用:
Button sendButton = (Button)sender;
e是你點擊事件的一些參數(shù)。
.Net Framework中的事件必要的兩個參數(shù),object sender 指的是事件監(jiān)視的對象, EventArgs 就是事件
所需要的數(shù)據(jù)?
?
sender 產生事件的對象
e 事件的參數(shù)?
========
總結
以上是生活随笔為你收集整理的.net (object sender, EventArgs e) 学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Bundle类 学习总结
- 下一篇: iframe学习总结