最近研究.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里也没找到调用,不知道是我理解错了,还是怎么回事 求指点。

解决方案 »

  1.   

    具体看看这篇文章介绍:http://www.cnblogs.com/zhili/archive/2012/10/29/ButtonClickEvent.html
      

  2.   

    什么“代理”,那个叫委托。事件是Control基类中实现的,当然你看不到。
      

  3.   

    在 ButtonBase 类中定义的。
    // 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);
    }
    }
      

  4.   

    关于你写的     public class Button : ButtonBase, IButtonControl
        {
            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个)然后触发它。
      

  5.   

    Button里就有事件,他调用你肯定看不到哦...
      

  6.   

    Winform和WPF的事件机制都是通过事件属性来实现的,http://msdn.microsoft.com/zh-cn/library/8843a9ch(v=vs.100).aspx MSDN里有详细的介绍,这里我就不贴出来了。建议你将.net的知识系统地看下吧。我现在就在看msdn。
      

  7.   

    http://www.tracefact.net/
    你可以去看看他里面讲的,还算清楚