当初csdn提供bolg的时候,我也凑热闹开通了一个,由于几年不做技术啦,一直也没开写。如今来到了新单位,居然又要开始做一些开发工作了,唉,想当年,俺用的是Vb6,开发了许多的GIS软件,那叫一个熟啊,现如今重操编程旧业,要用C#开发ArcEngine了,两个东东对我而言都是很新鲜的啊,学吧...
突然想到我还有个csdn bolg,写写学习心得吧, 今天是我学C#的第3天,ArcEngine的第4天,觉得delegate和事件好费解,可开发ArcEngine又很常用,比如:
((ICustomizeDialogEvents_Event)m_CustomizeDialog).OnCloseDialog += new ICustomizeDialogEvents_OnCloseDialogEventHandler(this.OnCloseDialog);
于是对比着button的click事件琢磨了一下这句代码的含义,理解如下:
(ICustomizeDialogEvents_Event)m_CustomizeDialog的作用是QI from ICustomDialog to ICustomizeDialogEvents_Event,对了C#里面习惯叫强制类型转换,QI(Query Interface)是AO里的叫法;然后就像.net frame的button类已经为开发者建立了(继承了)System.EventHandler这个delegate一样,ESRI.ArcGIS.ToolbarControl类也已经建立(应该是继承)了一个名为stomizeDialogEvents_OnCloseDialogEventHandler的delegate;同样的,.net frame的button类定义了button1.Click事件,这个事件其实是一个实例化的System.EventHandler(前面建立的delegate),ESRI.ArcGIS.ToolbarControl类也定义了ESRI.ArcGIS.ToolbarControl.ICustomizeDialogEvents_Event.OnCloseDialog事件;(不同之处在于这个事件定义在了ICustomizeDialogEvents_Event接口下),这个事件其实是一个实例化的ICustomizeDialogEvents_OnCloseDialogEventHandler(前面建立的delegate),.net frame的button类的button1.Click事件用法是自定义一个方法,然后在构造函数中调用该方法的多点delegate,ESRI.ArcGIS.ToolbarControl.ICustomizeDialogEvents_Event.OnCloseDialog事件的用法与此类似。
================================
事实上可以这样理解delegate和event,下面是C#高级编程中的一段例程,我加上了自己理解的注释:
事件服务器类负责定义delegate并创建一个event类型的delegate实力,这样事件处理器类可以通过这个delegate实例传递自己定义的方法。
事件服务器类:
using System;
namespace delegateSample
{
public class UserInputMonitor //事件服务器<或者叫事件发生器>类/对象(定义事件,发出事件通知的类)
{ //用于设置事件,相当于.net frame的一个特例(起到了类似的作用),.net frame相当于所有事件的发生器(服务器)
public delegate void UserreQuest(object sender,UserRequestEventArgs e);//可以把委托看成是事件句柄,以及对事件的描述,包括参数和返回值
public event UserreQuest OnUserRequest;//这里声明事件,事件是类/对象用于发出通知的成员,事件必须声明成delegate型的;同时这里实例化了一个对象
public void Run()
{
while(true)
{
Console.WriteLine("Please Select the perper item:");
Console.WriteLine(" Request AD--hit A to return;");
Console.WriteLine(" Request personal message from ballake----" + "hit P to return;");
Console.WriteLine(" Exit----hit X to return;");
string response=Console.ReadLine();
char responseChar=Convert.ToChar(response[0]);
switch(responseChar)
{
case 'A':
OnUserRequest(this,new UserRequestEventArgs(RequestType.ADRequest));
break;
case 'P':
OnUserRequest(this,new UserRequestEventArgs(RequestType.PersonalMessageRequest));
break;
case 'X':
return;
}
}
}
}
public enum RequestType{ADRequest,PersonalMessageRequest};
public class UserRequestEventArgs:EventArgs //定义事件参数的方法!!
{
public RequestType request;
public UserRequestEventArgs(RequestType request):base()
{
//
// TODO: 在此处添加构造函数逻辑
//
this.request=request;
}
public RequestType Request
{
get
{
return request;
}
}
}
}
事件处理器类 :
using System;
using System.Windows.Forms;
namespace delegateSample
{
public class MessageDisplayer//事件处理器类/对象(接受事件通知,并对事件作出相应处理)
{
public MessageDisplayer(UserInputMonitor monitor)
{
//button1....
monitor.OnUserRequest+=new UserInputMonitor.UserreQuest(UserRequestHandler);
}
protected void UserRequestHandler(object sender,UserRequestEventArgs e)
{
switch(e.request)
{
case RequestType.ADRequest:
Console.WriteLine("AD Information!");
break;
case RequestType.PersonalMessageRequest:
Console.WriteLine("ballake personal's Information!");
break;
}
}
}
public class ManagerStaffMonitor//事件处理器类/对象(接受事件通知,并对事件作出相应处理)
{
public ManagerStaffMonitor(UserInputMonitor monitor)
{
monitor.OnUserRequest+=new UserInputMonitor.UserreQuest(UserRequestHandler);
}
protected void UserRequestHandler(object sender,UserRequestEventArgs e)
{
if(e.request==RequestType.PersonalMessageRequest)
MessageBox.Show("henhen","i am saying...");
}
}
public class MainClass //主程序
{
public static void Main(string[] args)
{
UserInputMonitor inputmonitor=new UserInputMonitor();
MessageDisplayer mdisplayer=new MessageDisplayer(inputmonitor);
ManagerStaffMonitor msmonitor=new ManagerStaffMonitor(inputmonitor);
inputmonitor.Run();
}
}
}