最近研究.NET的事件和代理的实现,有点不明白的地方,就拿button控件的点击事件来举例子:namespace System
{
public delegate void EventHandler(object sender, EventArgs e);
//命名空间下定义一个代理
public class Button : ButtonBase, IButtonControl
{
public event EventHandler Click;
//button控件下定义个EVENT事件
} public partial class Form1 : Form
{
private System.Windows.Forms.Button button1;
//给FORM类定义一个成员 button1
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
//给button一个地址空间
this.button1.Click += new System.EventHandler(this.button1_Click);
//把button1_Click注册给button1
}
private void button1_Click(object sender, EventArgs e)
{
//单击函数的内容 } }
}
以上是我总结的.net下事件的定义方式,但是我没找到 this.button1.Click是在哪里被调用的以我的理解,应该在button类里有一个
public 函数名()
{
Click(object sender, EventArgs e)
}然后当我单击按钮之后在Form1里调用这个函数,可是在button类里找不到定义,Form1里也没找到调用,不知道是我理解错了,还是怎么回事 求指点。
{
public delegate void EventHandler(object sender, EventArgs e);
//命名空间下定义一个代理
public class Button : ButtonBase, IButtonControl
{
public event EventHandler Click;
//button控件下定义个EVENT事件
} public partial class Form1 : Form
{
private System.Windows.Forms.Button button1;
//给FORM类定义一个成员 button1
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
//给button一个地址空间
this.button1.Click += new System.EventHandler(this.button1_Click);
//把button1_Click注册给button1
}
private void button1_Click(object sender, EventArgs e)
{
//单击函数的内容 } }
}
以上是我总结的.net下事件的定义方式,但是我没找到 this.button1.Click是在哪里被调用的以我的理解,应该在button类里有一个
public 函数名()
{
Click(object sender, EventArgs e)
}然后当我单击按钮之后在Form1里调用这个函数,可是在button类里找不到定义,Form1里也没找到调用,不知道是我理解错了,还是怎么回事 求指点。
解决方案 »
- C#连接mysql时,向数据库中用 MySQLCommand插入数据存在参数应该怎么办?
- 怎样防止源文件被别人获取?
- TransparencyKey属性....
- throw e 总出现一个错误提示,不知道怎么解决
- 兄弟们,提点webservice安全的解决办法或方案,谢谢了!!!!1
- C#的PrintDocument控件怎么实现批量打印
- 一直都打得开的一套网站程序,请问为什么今天用vs2003打不开了啊?谢谢!
- C#中如何实现Windows资源管理器的左右分隔效果?
- 在哪里可以下载。NET开发环境与C#集成开发环境,首先声明,我们公司的电脑只能上中国的网站。
- 关于报表的问题,请各位高手指点一下,最好有源代码,谢谢
- 请问下c#中Atrribute类的使用?
- 新手,求帮助
// System.Windows.Forms.ButtonBase
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
protected override void WndProc(ref Message m)
{
int msg = m.Msg;
if (msg != 245)
{
if (this.OwnerDraw)
{
int msg2 = m.Msg;
if (msg2 > 243)
{
if (msg2 <= 517)
{
if (msg2 != 514 && msg2 != 517)
{
goto IL_E5;
}
}
else
{
if (msg2 != 520)
{
if (msg2 == 533)
{
goto IL_8C;
}
goto IL_E5;
}
}
try
{
this.SetFlag(8, true);
base.WndProc(ref m);
return;
}
finally
{
this.SetFlag(8, false);
}
goto IL_E5;
}
if (msg2 != 8 && msg2 != 31)
{
if (msg2 != 243)
{
goto IL_E5;
}
return;
}
IL_8C:
if (!this.GetFlag(8) && this.GetFlag(4))
{
this.SetFlag(4, false);
if (this.GetFlag(2))
{
this.SetFlag(2, false);
base.Invalidate(this.DownChangeRectangle);
}
}
base.WndProc(ref m);
return;
IL_E5:
base.WndProc(ref m);
return;
}
int msg3 = m.Msg;
if (msg3 == 8465)
{
if (NativeMethods.Util.HIWORD(m.WParam) == 0 && !base.ValidationCancelled)
{
this.OnClick(EventArgs.Empty);
return;
}
}
else
{
base.WndProc(ref m);
}
return;
}
if (this is IButtonControl)
{
((IButtonControl)this).PerformClick();
return;
}
this.OnClick(EventArgs.Empty);
}[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnClick(EventArgs e)
{
EventHandler eventHandler = (EventHandler)base.Events[Control.EventClick];
if (eventHandler != null)
{
eventHandler(this, e);
}
}
{
public event EventHandler Click;
//button控件下定义个EVENT事件
}这个代码,这显然不是.net控件的做法。在.net中,不管是winform或者别的什么平台,都不是这样保存事件委托的。比如一个控件有20个事件,运行时在进程内有1万个控件,那么是不是就有20万个你所谓的 Click 委托属性?不是的。这太浪费空间了。因此.net你的控件,是在组件父类中有一个 EventHandlerList 类型的委托集合。这样,假设一个有着20个事件定义的控件,运行时只有2个事件被使用到了,那么这个控件对象仅仅分配2个空间来保存它,而不是分配20个空间(其中18个指向null)。结果就是,你在所有 OnXXXXX 这类触发事件的代码中,都会看到类似 EventHandler eventHandler = (EventHandler)base.Events[某某事件的句柄定义];
if (eventHandler != null)
{
eventHandler(this, e);
}这种一摸一样的代码,它都是从事件委托集合中搜索到你要的那种类型的事件(也就是上面具有两个事件的委托集合中找到其中1个)然后触发它。
你可以去看看他里面讲的,还算清楚