解释用户控件中自定义事件的代码

时间:2010-10-22 15:40:42

标签: c# winforms events user-controls

有人给了我这个效果很好的代码。但我真的很想了解其中发生的事情。有人可以解释一下吗?代码的每个部分的含义是什么?代码位于自定义控件内,该控件在面板内有两个标签。

此外,我已经看到一些使用添加/删除语法的自定义控件事件,这是为了什么?与这里发生的事情有什么不同?

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    public event EventHandler MyCustomClickEvent;

    protected virtual void OnMyCustomClickEvent(EventArgs e)
    {
        // Here, you use the "this" so it's your own control. You can also
        // customize the EventArgs to pass something you'd like.

        if (MyCustomClickEvent != null)
            MyCustomClickEvent(this, e);
    }

    private void label1_Click(object sender, EventArgs e)
    {
        OnMyCustomClickEvent(EventArgs.Empty);
    }
}

4 个答案:

答案 0 :(得分:8)

请参阅下面的评论。还有一个更详细的事件我blogged关于这个概念,我将在后面详细介绍整个过程。

public partial class UserControl1 : UserControl
{
    //This is the standard constructor of a user control
    public UserControl1()
    {
        InitializeComponent();
    }

    //This defines an event called "MyCustomClickEvent", which is a generic
    //event handler.  (EventHander is a delegate definition that defines the contract
    //of what information will be shared by the event.  In this case a single parameter
    //of an EventArgs object.
    public event EventHandler MyCustomClickEvent;


    //This method is used to raise the event, when the event should be raised, 
    //this method will check to see if there are any subscribers, if there are, 
    //it raises the event
    protected virtual void OnMyCustomClickEvent(EventArgs e)
    {
        // Here, you use the "this" so it's your own control. You can also
        // customize the EventArgs to pass something you'd like.

        if (MyCustomClickEvent != null)
            MyCustomClickEvent(this, e);
    }

    private void label1_Click(object sender, EventArgs e)
    {
        OnMyCustomClickEvent(EventArgs.Empty);
    }
}

答案 1 :(得分:2)

我建议您阅读Events for C# on MSDN。详细介绍了这一点。

基本上,MyCustomClickEvent是一个事件。 OnMyCustomClickEvent方法用于引发事件,但是如果需要,子类也可以引发此事件。

单击“label1”时,会运行OnMyCustomClickEvent方法,从而引发事件。订阅该事件的任何代表都将在此时执行。

答案 2 :(得分:1)

您提到在某些自定义控件示例中看到事件的添加/删除语法。很可能这些示例是using the UserControl class' Events property来存储事件处理程序,例如在以下示例中:

    public event EventHandler MyEvent
    {
        add
        {
            Events.AddHandler("MyEvent", value);
        }
        remove
        {
            Events.RemoveHandler("MyEvent", value);
        }
    }

通常情况下,控件的使用者通常不想处理控件公开的每个事件。如果每个事件都被定义为“字段”事件(如您的示例所示),那么即使该事件没有订阅者,每个事件也会占用一块内存。当你有一个由数百个控件构成的复杂页面时,每个控件可能有几十个事件,未使用事件的内存消耗并不是无关紧要。

这就是System.ComponentModel.Component类(System.Windows.Forms.Control类的基类)具有Events属性的原因,该属性基本上是存储事件处理程序委托的字典。这样,每个事件的实现更像是属性而不是字段。每个事件的添加/删除处理程序存储或从Events字典中删除委托。如果未使用事件,则Events字典中没有条目,并且不会为该事件消耗额外的内存。做一些工作(必须查找事件处理程序)以节省更多内存是一种权衡。

编辑:修复了我对Windows Forms的回答,而不是ASP.NET,尽管概念是相同的。

答案 3 :(得分:0)

关于添加/删除,这是事件的“手动”实现。以下两个片段做同样的事情。

自动实施:

public event EventHandler MyEvent;

手动实施:

private EventHandler _myEvent;

public event EventHandler MyEvent
{
    add { _myEvent += value; }
    remove { _myEvent -= value; }
}

这与自动属性完全相同,其中:

public string Property { get; set; };

与:

完全相同
private string _property;

public string Property
{
    get { return _property; }
    set { _property = value; }
}

这些片段之间的区别在于,通过手动实现,您可以获得更多控制权。例如:

  • 在add / get和remove / set;
  • 中实现逻辑
  • 访问允许您设置的字段[非序列化];
  • 将值放在例如Dictionary

Form类,例如后者是否保持Form类中字段的数量。