如果上面我说的不清楚,我用代码演示一遍: 一个现实中的例子: 小王委托小张帮他监视小李,只要他一跳舞就去揍他,呵呵,好吧,我就用这个例子来说说C#中的DELEGATE,现在有三个类,呵呵,是小王,小张,小李。那么小张就是委托。 下面例子public class 小李 { public 小李(小张 obj) { // 构造器,传递小张的实例进来 } // 下面是小李的跳舞方法 public void 跳舞() { // 跳舞方法 把这个方法传递给小张 实例小张(this); } }下面我们来定义委托小张。 // 定义参数,把小李给传递进来,下面的object实际上就是小李的实例。 public delegate 小张(object sender);下面定义小王,小王不会别的,就会打人。:-) public class 小王 { public 小王 { // 构造器 }
// 小王打人方法 public void 揍(object obj) // obj参数就是要打的对象 { // 我打,我打打打!! } }下面是场景 public class 舞厅 { public int main() { new 实例小王; new 实例小张(小王.揍); \\这句是小王委托小张去监视小李 new 实例小李(小张);
呵呵,好长时间没有看这个帖子,好吧,我重新说一次。 还是上次的那个例子:比如说一个公司(场景),你是老板,手下有两个员工,小张和小李。你命令小张注意小李,在开发软件工作的时候如果上网打游戏,你就记录下来,从小李工资里扣100元钱。这个实际上就是现实中的委托。现在给出一个代码,C#控制台程序,编译运行通过 using System;namespace CSharpConsole { public class 场景 { [STAThread] public static void Main(string[] args) { Console.WriteLine("场景开始了...."); // 生成小王 小王 w = new 小王(); // 生成小账 小张 z = new 小张(); // 指定监视 z.PlayGame += new PlayGameHandler(w.扣钱);
// 开始玩游戏 z.玩游戏(); Console.WriteLine("场景结束..."); Console.ReadLine(); } } // 负责扣钱的人 public class 小王 { public 小王() { Console.WriteLine("生成小王..."); } public void 扣钱(object sender,EventArgs e) { Console.WriteLine("小王:好小子,上班时间胆敢玩游戏..."); Console.WriteLine("小王:看看你小子有多少钱..."); 小张 f = (小张)sender; Console.WriteLine("小张的钱: " + f.钱.ToString()); Console.WriteLine("开始扣钱......"); System.Threading.Thread.Sleep(500); f.钱 = f.钱 - 500; Console.WriteLine("扣完了....现在小张还剩下:" + f.钱.ToString()); } } // 如果玩游戏,则引发事件 public class 小张 { // 先定义一个事件,这个事件表示“小张”在玩游戏。 public event PlayGameHandler PlayGame; // 保存小张钱的变量 private int m_Money; public 小张() { Console.WriteLine("生成小张...."); m_Money = 1000; // 构造函数,初始化小张的钱。 } public int 钱 // 此属性可以操作小张的钱。 { get { return m_Money; } set { m_Money = value; } } public void 玩游戏() { Console.WriteLine("小张开始玩游戏了....."); Console.WriteLine("小张:CS好玩,哈哈哈! 我玩....."); System.Threading.Thread.Sleep(500); System.EventArgs e = new EventArgs(); OnPlayGame(e); } protected virtual void OnPlayGame(EventArgs e) { if(PlayGame != null) { PlayGame(this,e); } } } // 定义委托处理程序 public delegate void PlayGameHandler(object sender,System.EventArgs e); }
private static extern int SendMessage(
int hWnd, // handle to destination window
int Msg, // message
int wParam, // first message parameter
int lParam // second message parameter
); 3 消息的接受 在C#中,任何一个窗口都有也消息的接收处理函数,就是defproc函数 你可以在form中重载该函数来处理消息 protected override void DefWndProc ( ref System.WinForms.Message m )
{
switch(m.msg)
{
case WM_Lbutton :
///string与MFC中的CString的Format函数的使用方法有所不同
string message = string.Format("收到消息!参数为:{0},{1}",m.wParam,m.lParam);
MessageBox.Show(message);///显示一个消息框
break;
default:
base.DefWndProc(ref m);///调用基类函数处理非自定义消息。
break;
}
}
其实,C#中的事件也是通过封装系统消息来实现的,如果你在DefWndProc函数中不处理该
那么,他会交给系统来处理该消息,系统便会通过代理来实现鼠标单击的处理函数,因此你可以通过
defproc函数来拦截消息,比如你想拦截某个按钮的单击消息 4 C#中其他的消息处理方法
在C#中有的时候需要对控件的消息进行预处理,比如你用owc的spreedsheet控件来处理Excel文件,你不想让用户可以随便选中
数据进行编辑,你就可以屏蔽掉鼠标事件,这个时候就必须拦截系统预先定义好的事件(这在MFC中称为子类化),你可以通过C#提供的一个接口
IMessageFilter来实现消息的过滤
public class Form1: System.Windows.Forms.Form,IMessageFilter
{
const int WM_MOUSEMOVE = 0x200
public bool PreFilterMessage(ref Message m)
{ Keys keyCode = (Keys)(int)m.WParam & Keys.KeyCode;
if(m.Msg == m.Msg==WM_MOUSEMOVE) //||m.Msg == WM_LBUTTONDOWN
{
//MessageBox.Show("Ignoring Escape...");
return true;
}
return false;
}
}
1。声明一个委托
public delegete void delegateME();
2。声明此委托的事件
public event delegateME eventME;
3。把方法订阅到一个事件
eventME+=new delegete(objA.Method);
括号里传递的是需要订阅事件的方法。
然后在别处运行eventME将调用objA.Method方法。如果想进一步了解C#中的事件处理机制,编写自己的事件可参看
http://www.csdn.net/develop/Read_Article.asp?Id=22951
>>一个代表声明定义了一个从类System.Delegate 延伸的类
委托及其角色
委托是 .NET 框架内的常用类,用于生成事件处理机制。委托大体上相当于常用于 C++ 和其他面向对象的语言中的函数指针。但与函数指针不同的是,委托是面向对象的、类型安全的和保险的。另外,函数指针只包含对特定函数的引用,而委托由对对象的引用以及对该对象内一个或多个方法的引用组成。此事件模型使用“委托”将事件绑定到用来处理它们的方法。委托允许其他类通过指定处理程序方法注册事件通知。当发生事件时,委托调用绑定的方法。委托可绑定到单个方法或多个方法,后者又称为多路广播。当创建事件的委托时,您(或“Windows 窗体设计器”)通常创建多路广播事件。极少的例外情况是,某个事件会导致特定过程(如显示对话框),而该过程在逻辑上不在每个事件中重复多次。多路广播委托维护它所绑定到的方法的调用列表。多路广播委托支持将方法添加到调用列表的 Combine 方法以及移除它的 Remove 方法。 当应用程序记录某个事件时,控件通过调用该事件的委托引发事件。委托接着调用绑定的方法。最常见的情况(多路广播委托)是,委托依次调用调用列表中的每个绑定方法,这样可提供一对多通知。此策略意味着控件不需要维护事件通知的目标对象的列表,即委托处理所有注册和通知。 委托也允许将多个事件绑定到同一个方法,从而允许多对一通知。例如,单击按钮事件和单击菜单命令事件可调用同一委托,然后该委托调用单个方法以相同方式处理各个事件。委托使用的绑定机制是动态的,即委托可在运行时绑定到其签名与事件处理程序的签名匹配的任何方法。此功能使您得以根据条件设置或更改绑定的方法,并动态地将事件处理程序附加到控件上。
ms-help://MS.NETFrameworkSDK.CHS/cpguidenf/html/cpconWhatIsEvent.htm
这是2002的sdk文档
>>一个代表声明定义了一个从类System.Delegate 延伸的类
正是!
先解释一下:在下来论坛的次数不多,所以论坛的有些功能不是很熟,比如搜索,我都不知道在那里,让大家见笑了,请大家顺手指点一下。另外想问一下论坛有没有离线资料包和阅读器下载,谢谢。
回到问题中,举一个例子来说,比如要设计一个button类,并要使这个类的实例能响应onclick事件, 我这样做:
1、在 button类中申明一个委托类
public delegate void myclick(object sender);
2、在 button类中申明一个onclick事件,这个事件是上边委托类的实例
public event myclick onclick;
-----------在button类中作这两步是不是就齐活了?(语法不一定对,就这个意思了) 另外有一个form对象中创建了一个上边的button的实例button1,而且要在单击button1调用这个form的一个方法 public void button1click(object sender);,也就是把form的button1click方法注册到button1的onclick事件,是不是在form的构造方法中
button1.onclick+=button1click (这里不对吧,应该怎么做?)---------------------我上边的理解肯定有问题吧,大虾们给指导一下。
这样吗?好像也不对吧
1、我上边在button类中申明onclick事件的做法对不对?
2、我在form中把button1click方法注册到button1的onclick事件的做法对不对?
另外,楼上所说的本来是我搞清楚基本概念之后接下来要问的:
事件的调用列表是一什么样的形式放在那里的?
一个现实中的例子:
小王委托小张帮他监视小李,只要他一跳舞就去揍他,呵呵,好吧,我就用这个例子来说说C#中的DELEGATE,现在有三个类,呵呵,是小王,小张,小李。那么小张就是委托。
下面例子public class 小李
{
public 小李(小张 obj)
{
// 构造器,传递小张的实例进来
} // 下面是小李的跳舞方法
public void 跳舞()
{
// 跳舞方法
把这个方法传递给小张
实例小张(this);
}
}下面我们来定义委托小张。
// 定义参数,把小李给传递进来,下面的object实际上就是小李的实例。
public delegate 小张(object sender);下面定义小王,小王不会别的,就会打人。:-)
public class 小王
{
public 小王
{
// 构造器
}
// 小王打人方法
public void 揍(object obj) // obj参数就是要打的对象
{
// 我打,我打打打!!
}
}下面是场景
public class 舞厅
{
public int main()
{
new 实例小王; new 实例小张(小王.揍);
\\这句是小王委托小张去监视小李
new 实例小李(小张);
实例小李.跳舞;
// 小李一跳舞,那就要被打了。:-)
}
}
不过在你的例子中在下还有一些疑问,请再指教一下:
1、 public 小李(小张 obj)
{
// 构造器,传递小张的实例进来
}
--------------这里,委托小张的实例是在外边创建,然后通过小李的构造方法传入吗?
我觉得应该在小李的构造方法中创建,不知我的理解对不对?
2、如果我还要在小李跳舞的时候,执行 小赵.关门,小钱.放狗...怎么作? 也就是有多个对象监视小李跳舞,并采取相应的措施?
事件得需什么东西激活它,而委托则是主动执行的.这个是个相对的概念.委托有点类似于VC的callback.搂主可以看看delegate的一般使用就能够体会到的.
----顺便问一句,vc的事件也用的是callback机制吗?我对vc一窍不通。
讲的很精彩,鼓掌!!!
TomMax(笑望人生) 讲的确实很精彩,但是取不见得对(我认为 : ) 也许是我理解错了)
请大侠回来再指点一二,谢谢
感觉好像又没有他都可以阿!
讲的很精彩,鼓掌!!!
的例子中没有使用到 event,
可否再用同样的方式阐述一下。
通俗一点就像马桶,可以不同的人坐上去,排泄物可以通到不同的地方,但是屁股必须要和马桶尺寸完全一样
还是上次的那个例子:比如说一个公司(场景),你是老板,手下有两个员工,小张和小李。你命令小张注意小李,在开发软件工作的时候如果上网打游戏,你就记录下来,从小李工资里扣100元钱。这个实际上就是现实中的委托。现在给出一个代码,C#控制台程序,编译运行通过
using System;namespace CSharpConsole
{
public class 场景
{
[STAThread]
public static void Main(string[] args)
{
Console.WriteLine("场景开始了....");
// 生成小王
小王 w = new 小王();
// 生成小账
小张 z = new 小张(); // 指定监视
z.PlayGame += new PlayGameHandler(w.扣钱);
// 开始玩游戏
z.玩游戏(); Console.WriteLine("场景结束...");
Console.ReadLine();
}
} // 负责扣钱的人
public class 小王
{
public 小王()
{
Console.WriteLine("生成小王...");
} public void 扣钱(object sender,EventArgs e)
{
Console.WriteLine("小王:好小子,上班时间胆敢玩游戏...");
Console.WriteLine("小王:看看你小子有多少钱...");
小张 f = (小张)sender;
Console.WriteLine("小张的钱: " + f.钱.ToString());
Console.WriteLine("开始扣钱......");
System.Threading.Thread.Sleep(500);
f.钱 = f.钱 - 500;
Console.WriteLine("扣完了....现在小张还剩下:" + f.钱.ToString());
}
} // 如果玩游戏,则引发事件
public class 小张
{
// 先定义一个事件,这个事件表示“小张”在玩游戏。
public event PlayGameHandler PlayGame;
// 保存小张钱的变量
private int m_Money; public 小张()
{
Console.WriteLine("生成小张....");
m_Money = 1000; // 构造函数,初始化小张的钱。
} public int 钱 // 此属性可以操作小张的钱。
{
get
{
return m_Money;
}
set
{
m_Money = value;
}
} public void 玩游戏()
{
Console.WriteLine("小张开始玩游戏了.....");
Console.WriteLine("小张:CS好玩,哈哈哈! 我玩.....");
System.Threading.Thread.Sleep(500);
System.EventArgs e = new EventArgs();
OnPlayGame(e);
} protected virtual void OnPlayGame(EventArgs e)
{
if(PlayGame != null)
{
PlayGame(this,e);
}
}
} // 定义委托处理程序
public delegate void PlayGameHandler(object sender,System.EventArgs e);
}