C#自定義控制元件-事件-委託
理解C#程式設計中的元件-事件-委託
首先建立一個Windows控制元件專案,新增如下控制元件樣板:
當事件觸發時,會傳遞一個EventArgs型別的引數給事件處理方法,為了能傳遞自定義的資訊,我們可以建立一個繼承於EventArgs的事件引數類,其定義如下:
- publicclass EventLoginArgs:System.EventArgs
- {
- publicstring strUserID;
- publicstring strUserName;
- publicstring strUserPWD;
- publicbool bVaild;
- public EventLoginArgs(
- string userID,string userName,string userPWD)
- {
- strUserID = userID;
- strUserName = userName;
- strUserPWD = userPWD;
- }
再宣告兩個委託,它們是對EventLoginArgs和EventArgs物件中的資訊的封裝,如下:
- publicdelegatevoid UserLoginEventHandler(
- object sender,EventLoginArgs e);
- publicdelegatevoid CancelEventHandler(
- object sender,EventArgs e);
在元件中為了能讓使用者自定義某事件的處理方法,所以元件必需提供事件介面.如果只是繼承於單個已有的Windows控制元件,可以過載已知的方 法進行新增自己的處理,也可以宣告自定義的事件介面.而若元件中包含多個控制元件,應該根據實際需要宣告事件介面,此處本人就兩個按鈕的 使用而宣告兩個自定義的事件介面,如下:
- publicevent UserLoginEventHandler SubmitLogin;
- publicevent CancelEventHandler Cancel;
- protectedvirtualvoid OnSubmitLogin(EventLoginArgs e)
- {
- if(this.SubmitLogin!=null)
- {
- SubmitLogin(this,e);
- }
- }
- protectedvirtualvoid OnCancel(EventArgs e)
- {
- if(this.Cancel!=null)
- {
- Cancel(this,e);
- }
其實SubmitLogin 是UserLoginEventHandler委託的例項,令人費解的是此事件的觸發,傳遞,處理過程如何呢?
在本例中是通過確定按鈕來觸發submitLogin事件的:
- privatevoid 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事件的響應程式,如下:
- privatevoid 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 isin test form!
- thisis the process in DB
- thisis 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中處理結果,下面的是例子二的主要程式碼:
- publicdelegatevoid UserLoginEventHandler(
- object sender,EventLoginArgs e);
- publicdelegatevoid CancelEventHandler(
- object sender,EventArgs e);
- publicevent UserLoginEventHandler SubmitLogin;
- publicevent CancelEventHandler Cancel;
- protectedvirtualvoid OnSubmitLogin(EventLoginArgs e)
- {
- if(this.SubmitLogin!=null)
- {
- SubmitLogin(this,e);
- }
- }
- protectedvirtualvoid OnCancel(EventArgs e)
- {
- if(this.Cancel!=null)
- Cancel(this,e);
- }
- publicstring Server
- {
- }
- publicstring DataBase
- {
- }
- publicstring TableSet
- {
- }
- publicstring UserForDB
- {
- }
- publicstring PWDForDB
- {
- }
- publicbool 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);
- returnfalse;
- }
- 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;
- }
- privatevoid 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);
- }
- }
- privatevoid btnCancel_Click(
- object sender, System.EventArgs e)
- {
- OnCancel(e);
- }
- privatevoid UserControl_Load(
- object sender, System.EventArgs e)
- {
- intLoginTime = 0;
- }
- }
- publicclass EventLoginArgs:System.EventArgs
- {
- publicstring strUserID;
- publicstring strUserName;
- publicstring strUserPWD;
- publicbool bVaild;
- public EventLoginArgs(
- string userID,string userName,string userPWD)
- {
- strUserID = userID;
- strUserName = userName;
- strUserPWD = userPWD;
- }
- }
它的客戶程式主要如下:
- privatevoid 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);
- }
- privatevoid 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,可參考擴充套件例子二。