深入理解C#编程中的组件-事件-委托

2016-02-19 16:17 0 1 收藏

图老师小编精心整理的深入理解C#编程中的组件-事件-委托希望大家喜欢,觉得好的亲们记得收藏起来哦!您的支持就是小编更新的动力~

【 tulaoshi.com - 编程语言 】

  在组件编程中对事件的理解是十分重要的,C# 中的事件是当对象发生某些有趣的事情时,类向该类的客户提供通知的一种方法。与事件联系最为紧密的,个人认为是委托.委托可以将方法引用封装在委托对象内。为了弄清组件-事件-委托三者的关系,本人用实际的例子来谈 谈小弟的理解。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  首先创建一个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 DBthis is the btnOK_click function!

  结果表明单击btnOK按钮时执行组件中的OnSubmitLogin(new EventLoginArgs(txtID.Text,txtName.Text,txtPWD.Text)),此方法又调用 SubmitLogin(this,e),从而激发SubmitLogin事件,userControl1_SubmitLogin就进行响应,故打印第一行。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  跟着是执行TestUserInDB,它打印出第二行。

  最后是返回到btnOK_Click中输出最后一行。

  注意若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+" whereUserID='"+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);elseOnSubmitLogin(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";}

  读者可以参考学习,也可直接使用此组件,但使用时应当以Microsoft SQL Server 作为后台数据库,所用到的用户表格应有 UserID,UserName,UserPWD三列,同时在客户程序中应对有关参数初始化,SubmitLogin事件返回值是尝试次数intLoginTime和验证是否成功bLogin,可参考扩展例子二。

来源:https://www.tulaoshi.com/n/20160219/1611567.html

延伸阅读
首先介绍一下什么是Map。在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value。这就是我们平时说的键值对。 HashMap通过hashcode对其内容进行快速查找,而 TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(Has...
很多初学c#的朋友对于事件与接口感到迷惑不解,不明白它们之间的关系,下面我就用实例来简单的分析讲解一下。 事件,用event修饰符来代表一个事件,我们要创建一个C#事件必须按以下顺序来扫行: 1,创建或标识一个代表。比如下例中的 public delegate void dele(); //声明代表,delegate 关键字通知编译器 dele 是一个委托类...
标签: Delphi
一、窗口的创建 VCL 中,具有句柄(Handle) 属性的真正窗口控件全部继承自 TWinControl,那就从 TWinControl 的创建开始说起。 VCL 中窗口的建立不是按照我们想象中的流程创建的,即先把所有的窗口都创建好,然后再调用,而是在需要时才创建。可能你还不能理解我这句话的意思,慢慢看。继承自 TWinControl 的窗口控件都会有 ...
一提到访问控制符protected,即使是初学者一般都会很自信的认为自己在这方面的理解没有问题。那好,我们提一个问题出来看看..... 请看下面两端代码,其中包B中的猫和鼠都继承了动物类。 代码如下: //代码1:包A中有一个动物类  package testa;  public class Animal {      protected void crowl(String ...
标签: 服务器
Linux系统进程深入理解   1. 什么是进程 进程是处于执行期的程序以及它所包含的所有资源的总称,包括虚拟处理器,虚拟空间,寄存器,堆栈,全局数据段等。 在Linux中,每个进程在创建时都会被分配一个数据结构,称为进程控制块(Process Control Block,简称PCB)。PCB中包含了很多重要的信息,供系统调度和进程本身执行使...

经验教程

799

收藏

91
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部