C#編程中的組件-事件-委托
在組件編程中對事件的理解是十分重要的,C# 中的“事件”是當對象發生某些有趣的事情時,類向該類的客戶提供通知的一種方法。與事件聯系最為緊密的,個人認為是委托.委托可以將方法引用封裝在委托對象內。為了弄清組件-事件-委托三者的關系,本人用實際的例子來談談自己的理解。
理解C#編程中的組件-事件-委托
首先創建一個Windows控件項目,添加如下控件樣板:
當事件觸發時,會傳遞一個EventArgs類型的參數給事件處理方法,為了能傳遞自定義的信息,我們可以創建一個繼承于EventArgs的事件參數類,其定義如下:
- public class EventLoginArgs:System.EventArgs
- {
- public string strUserID;
- public string strUserName;
- public string strUserPWD;
- public bool bVaild;
- public EventLoginArgs(string userID,string userName,string userPWD)
- {
- strUserID = userID;
- strUserName = userName;
- strUserPWD = userPWD;
- }
再聲明兩個委托,它們是對EventLoginArgs和EventArgs對象中的信息的封裝,如下:
- public delegate void UserLoginEventHandler(object sender,EventLoginArgs e);
- public delegate void CancelEventHandler(object sender,EventArgs e);
在組件中為了能讓用戶自定義某事件的處理方法,所以組件必需提供事件接口.如果只是繼承于單個已有的Windows控件,可以重載已知的方 法進行添加自己的處理,也可以聲明自定義的事件接口.而若組件中包含多個控件,應該根據實際需要聲明事件接口,此處本人就兩個按鈕的 使用而聲明兩個自定義的事件接口,如下:
- public event UserLoginEventHandler SubmitLogin;
- public event CancelEventHandler Cancel;
- protected virtual void OnSubmitLogin(EventLoginArgs e)
- {
- if(this.SubmitLogin!=null)
- {
- SubmitLogin(this,e);
- }
- }
- protected virtual void OnCancel(EventArgs e)
- {
- if(this.Cancel!=null)
- {
- Cancel(this,e);
- }
其實SubmitLogin 是UserLoginEventHandler委托的實例,令人費解的是此事件的觸發,傳遞,處理過程如何呢?
在本例中是通過確定按鈕來觸發submitLogin事件的:
- private void btnOK_Click(object sender, System.EventArgs e)
- {
- if(txtID.Text != ""&&txtName.Text !=""&&txtPWD.Text !="")
- {
- intLoginTime++;
- OnSubmitLogin(new EventLoginArgs(txtID.Text,txtName.Text,txtPWD.Text));
- bLogin = TestUserInDB(new EventLoginArgs(txtID.Text,txtName.Text,txtPWD.Text));
- MessageBox.Show("this is the btnOK_click function!","In control",MessageBoxButtons.OK);
- if(!bLogin)
- MessageBox.Show("Login in Failed!","Login Error",MessageBoxButtons.OK);
- }
- else
- {
- MessageBox.Show("Your must input all the items!","Login Info",MessageBoxButtons.OK);
- }
- }
注意本例中的對話框是為了幫助了解事件的過程,真正有用的是第二個例子。
在btnOK_Click事件響應中,先對進行簡單的有效性檢查,建議實際工作應作加強完善.intLoginTime變量是嘗試登錄的次數.TestUserInDB是 通過已知信息在數據庫中搜索出有關記錄進行判斷用戶是否合法. 因為組件的測試是通過客戶程序的,所以應該創建一個最簡單明了的客戶 程序.這是一個Windows應用程序,將編譯好的組件添加到用戶控件欄中,拖出到工作區中,添加SubmitLogin事件的響應程序,如下:
- private void userControl1_SubmitLogin(object sender, Userlogin.EventLoginArgs e)
- {
- MessageBox.Show("This is in test form!"+ userControl1.bLogin +"\ns Login times is
- "+userControl1.intLoginTime +"\ne's strUserID="+e.strUserID,"Test",MessageBoxButtons.OK);
- }
此時運行客戶程序可得以下結果:
- This is in test form!
- this is the process in DB
- this is the btnOK_click function!
結果表明單擊btnOK按鈕時執行組件中的OnSubmitLogin(new EventLoginArgs(txtID.Text,txtName.Text,txtPWD.Text)),此方法又調用 SubmitLogin(this,e),從而激發SubmitLogin事件,userControl1_SubmitLogin就進行響應,故打印***行。
跟著是執行TestUserInDB,它打印出第二行。
***是返回到btnOK_Click中輸出***一行。
C#編程中的組件-事件-委托:例子二
注意若btnOK_Click中的OnSubmitLogin和TestUserInDB所在的行調換位置,其結果是不同的.第二個例子中,二者的位置調換,先進行數據庫 查詢判斷,再在SubmitLogin的事件響應userControl1_SubmitLogin中處理結果,下面的是例子二的主要代碼:
- public delegate void UserLoginEventHandler(object sender,EventLoginArgs e);
- public delegate void CancelEventHandler(object sender,EventArgs e);
- public event UserLoginEventHandler SubmitLogin;
- public event CancelEventHandler Cancel;
- protected virtual void OnSubmitLogin(EventLoginArgs e)
- {
- if(this.SubmitLogin!=null)
- {
- SubmitLogin(this,e);
- }
- }
- protected virtual void OnCancel(EventArgs e)
- {
- if(this.Cancel!=null)
- Cancel(this,e);
- }
- public string Server
- {
- }
- public string DataBase
- {
- }
- public string TableSet
- {
- }
- public string UserForDB
- {
- }
- public string PWDForDB
- {
- }
- public bool TestUserInDB(EventLoginArgs e)
- {
- //MessageBox.Show("this is the process for DB!","TestUserInDB",MessageBoxButtons.OK);
- bool bOK = false;
- if(this.strDataBase!=null && this.strServer!=null && this.strUserForDB!=null)
- {
- if(this.strPWDForDB==null)
- this.strPWDForDB = "";
- string strConnection = "server="+this.strServer +";database="+this.strDataBase
- +";UID="+this.strUserForDB +";PWD="+this.strPWDForDB;
- string strSQL = "select UserID,UserName,UserPWD from "+this.strTableSet+" where
- UserID='"+e.strUserID+"' and UserName='"+e.strUserName +"' and UserPWD='"+e.strUserPWD+"'";
- SqlConnection conn = new SqlConnection(strConnection);
- try
- {
- conn.Open();
- }
- catch(SqlException ex)
- {
- MessageBox.Show("數據庫不能打開!請檢查有關參數.","Error",MessageBoxButtons.OK);
- return false;
- }
- SqlDataAdapter da = new SqlDataAdapter(strSQL,conn);
- DataSet ds = new DataSet();
- try
- {
- da.Fill(ds,this.strTableSet);
- }
- catch(SqlException ex)
- {
- ......
- }
- foreach(DataRow row in ds.Tables[this.strTableSet].Rows)
- {
- if(row != null)
- {
- bOK = true;
- }
- }
- .......
- }
- else
- {
- bOK = false;
- }
- return bOK;
- }
- private void btnOK_Click(object sender, System.EventArgs e)
- {
- if(txtID.Text != ""&&txtName.Text !=""&&txtPWD.Text !="")
- {
- intLoginTime++;
- bLogin = TestUserInDB(new EventLoginArgs(txtID.Text,txtName.Text,txtPWD.Text));
- if(!bLogin)
- MessageBox.Show("Login in Failed!","Login Error",MessageBoxButtons.OK);
- else
- OnSubmitLogin(new EventLoginArgs(txtID.Text,txtName.Text,txtPWD.Text));
- }
- else
- {
- MessageBox.Show("Your must input all the items!","Login Info",MessageBoxButtons.OK);
- }
- }
- private void btnCancel_Click(object sender, System.EventArgs e)
- {
- OnCancel(e);
- }
- private void UserControl_Load(object sender, System.EventArgs e)
- {
- intLoginTime = 0;
- }
- }
- public class EventLoginArgs:System.EventArgs
- {
- public string strUserID;
- public string strUserName;
- public string strUserPWD;
- public bool bVaild;
- public EventLoginArgs(string userID,string userName,string userPWD)
- {
- strUserID = userID;
- strUserName = userName;
- strUserPWD = userPWD;
- }
- }
它的客戶程序主要如下:
- private void userControl1_SubmitLogin(object sender, Userlogin.EventLoginArgs e)
- {
- MessageBox.Show("This result is bLogin="+ userControl1.bLogin +" At "+userControl1.intLoginTime +" times \n
- UserID="+e.strUserID+"\n UserName="+e.strUserName,"TestResult",MessageBoxButtons.OK);
- }
- private void Form1_Load(object sender, System.EventArgs e)
- {
- userControl1.Server = "localhost";
- userControl1.DataBase="weiwen";
- userControl1.TableSet = "TestUser";
- userControl1.UserForDB="sa";
- userControl1.PWDForDB = "sa";
- }
以上就對C#編程中的組件-事件-委托做出了一些介紹。讀者可以參考學習,也可直接使用此組件,但使用時應當以Microsoft SQL Server 作為后臺數據庫,所用到的用戶表格應有 UserID,UserName,UserPWD三列,同時在客戶程序中應對有關參數初始化,SubmitLogin事件返回值是嘗試次數intLoginTime和驗證是否成功bLogin,可參考擴展例子二。
【編輯推薦】