技术开发 频道

C#事件与委托过程分析

  【IT168 技术文档】

  简述
  
在.NET应用程序开发中,有很多定义好的事件,如click,Keydown,Enter等,这些事件就有点类似委托的概念,只不过委托更灵活,可以在不同的界面上传递参数而返回需要的结果值。在C#中,增加了一个新的数据类型,即Delegate(委托),Delegate可以被认为是一种基于Object类的、类型安全的函数指针,它可以定义多个方法。委托处理问题更类似于C++的函数指针和Java语言中的接口,其代码是安全的,可管理的。委托最重要的应用就是定义事件,我们可以使用委托将方法的引用压缩到委托对象中,委托对象能被传递给调用该方法引用的代码,也就是说在事件中向委托传递参数,委托会返回一个具体的值,而不需要把每个方法都写在代码中。

  委托是不需要具体知道需要引用哪个类,关键的就是方法的描述类型和引用类型要与委托所匹配,所以在定义事件数据的类时,一般定义Object类(任何类都是继承Object类),当然如果你具体知道使用的类型,可以直接定义string、int……等等。

  在.NET应用程序开发中,有很多定义好的事件,如click,Keydown,Enter等,这些事件就有点类似委托的概念,只不过委托更灵活,可以在不同的界面上传递参数而返回需要的结果值。在C#中,增加了一个新的数据类型,即Delegate(委托),Delegate可以被认为是一种基于Object类的、类型安全的函数指针,它可以定义多个方法。委托处理问题更类似于C++的函数指针和Java语言中的接口,其代码是安全的,可管理的。委托最重要的应用就是定义事件,我们可以使用委托将方法的引用压缩到委托对象中,委托对象能被传递给调用该方法引用的代码,也就是说在事件中向委托传递参数,委托会返回一个具体的值,而不需要把每个方法都写在代码中。  委托是不需要具体知道需要引用哪个类,关键的就是方法的描述类型和引用类型要与委托所匹配,所以在定义事件数据的类时,一般定义Object类(任何类都是继承Object类),当然如果你具体知道使用的类型,可以直接定义string、int……等等。

  组成事件的三因素


  1.提供事件数据的类——公共使用的类

  事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。该类必须从 System.EventArgs(它是事件数据的基类)导出。代码如下:

public class ExportEventArgs: EventArgs { public object mxnum; public object Exportmxnum { get{return mxnum;} } public ExportEventArgs(object mxnum) { this.mxnum = mxnum; } }


  
  2.事件委托

  代码如下:

public delegate void ExportEventHandler(object sender, ExportEventArgs e); public event ExportEventHandler Export;//事件的定义


  3.引发事件的类或直接定义一个函数引发事件

  代码如下:

protected virtual void OnExport(ExportEventArgs e) { if (Export!= null) { //Invokes the delegates. Export (this, e); } }

   当控件中执行OnExport这个函数时,会触发事件,并将e作为事件的参数。定义函数代码如下:

public void ExportSelect(string mxnum) { ExportEventArgs ExportArgs = new ExportEventArgs (mxnum); // 利用委托来触发事件。通过 ExportEventArgs传递的参数集初始化事件 // 必须匹配委托ExportEventHandler的签名. Export (this, ExportArgs); }


   ExportEventArgs是从EventArgs派生的向事件传递参数集的类,在调用引发事件的类或调用ExportEventArgs类时触发事件,传回e参数,从而ExportEventArgs传回数据。

  示例:做一个用户控件,在用户控件中生成一个DataSet,访问一个服务器的数据信息,然后在Windosw应用程序中,通过传递一个参数,然后用户控件返回一个dataSet,在DataGrid中显示出来。

  新建一个项目,选择类,生成解决方案,然后删除刚才创建的类,添加用户控件UserControl1.cs。然后我们在用户控件类的里面开始定义委托声明,代码如下:

public class ExportEventArgs :EventArgs { private object mxnum; public object Exportmxnum { get{return mxnum;} } public ExportEventArgs(object mxnum) { this.mxnum=mxnum; } } public delegate void ExportEventHandler(object sender,ExportEventArgs e); public event ExportEventHandler Export; //生成一个函数调用委托事件 public void ExportSelect(object mxnum) { ExportEventArgs ExArgs=new ExportEventArgs(mxnum); Export(this,ExArgs); }


  当然也可以生成OnExport函数,由于还需要在应用程序中定义ExportEventArgs 类,所以直接在函数中定义好。

  从数据连接拖过来一个表,生成dataSet1, sqlDataAdapter1.表中有mxnum字段,利用适配器为它设置一个条件@part,为了在接受事件的类中传给mxnum字段一个值,所以我们为用户控件定义了一个属性mxnum。可以修改名字)如图1-1所示。

图1-1:用户控件的属性mxnum


  用户控件的属性,为了传回一个@part参数值,代码如下:

private string part; public string mxnum { get{return part;} set{part=value;} }


   这时再拖过来一个button1按钮,在应用程序中我们通过附值mxnum属性传来的part值给sqlDataAdapter1的参数,然后利用ExportSelect把dataSet1调回到ExportEventArgs类中,再传回一个结果。代码如下:

private void button1_Click(object sender, System.EventArgs e) { sqlDataAdapter1.SelectCommand.Parameters["@part"].Value=this.part; sqlDataAdapter1.Fill(this.dataSet11.BOM); ExportSelect(this.dataSet11); }


    添加一个项目,windows应用程序,添加一个textbox1,在textbox1的textBox1的TextChanged事件中写入:“//向用户控件的mxnum属性附值“。代码如下:

userControl11.mxnum=this.textBox1.Text;


    然后把用户控件拖到Windows应用程序中,点击用户控件的事件属性,找到Export事件,向里面写入如下代码:

private void userControl11_Export(object sender, Test1.UserControl1.ExportEventArgs e) { DataSet ds=(DataSet)e.Exportmxnum; dataGrid1.DataSource=ds.Tables[0].DefaultView; //如果知道表名,可以直接写table[“tablename”] }


   这时,我们通过在textBox1.text中输入一个具体的值,userControl11.mxnum属性就会通过Export事件,传给button1_Click事件一个@part,然后再通过委托返回一个dataSet,这样在DataGrid中就可以把委托的内容显示出来。

 

   作者简介:赵宇;Itpub .NET开发技术版版主;曾开发ERP、SQL Server 2000、Oracle的开发。

 

0
相关文章