为什么ASP.NET控件上的事件处理程序属性的属性有一个前缀(Load事件处理程序的OnLoad)

Mic*_*out 4 asp.net aspnet-compiler

这只是为了更好地理解ASP.NET框架.当您以声明方式(即Web表单标记)使用控件时,您可以使用以以下内容开头的属性通过其方法名称分配事件处理程序On:

<asp:Button runat="server" OnClick="..."/>
Run Code Online (Sandbox Code Playgroud)

但是当你查看System.Web.UI.WebControls.Button类时,它有一个名为Click委托被指定为的DelegHandler属性:

button.Click += new EventHandler(...);
Run Code Online (Sandbox Code Playgroud)

那么这是如何实现的呢?这仅仅是解析器遵循的约定吗?

我知道,这是一个奇怪的问题,答案只会满足我的好奇心.

Ian*_*ths 6

这是ASP.NET使用的命名约定,它非常无用,看起来与.NET中广泛使用的另一种常见命名约定相同.尽管有明显的相似性,但这两个公约是无关的.

.NET范围的约定在这里变得无关紧要,因为事件通常具有引发事件的相应方法,并且通过向On事件名称添加前缀来形成这些方法的名称.例如,Click提供的事件ButtonOnClick引发该事件的方法有关(如此处的另一个答案中所述).

混乱的部分是OnClick 方法什么做的OnClick 属性,这个问题的关注.

OnSomeEvent通过编写没有任何此类方法的控件,可以很容易地证明这些方法无关紧要.这是一个简单的用户控件的代码隐藏:

public partial class EventWithoutMethod : System.Web.UI.UserControl
{
    public event EventHandler Foobar;

    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        if (Foobar != null)
        {
            Foobar(this, EventArgs.Empty);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这声明了一个Foobar事件.(它实际上从未提出它,但这对于探索而言并不重要.)它没有定义OnFoobar方法.然而,OnSomeEvent当我们使用控件时,ASP.NET非常高兴我们使用约定:

<user:EventWithoutMethod runat="server" OnFoobar="FooHandler" />
Run Code Online (Sandbox Code Playgroud)

事实上,它不仅对我们这样做感到高兴,它实际上需要它.即使我的控件没有定义任何被调用OnFoobar的成员- 该事件被调用Foobar- OnFoobar如果我想从我的.aspx文件中附加事件处理程序,我必须写.如果我只是Foobar在其中放置一个属性来尝试附加事件,那么处理程序将永远不会运行.(无用的是,ASP.NET在您执行此操作时不会生成错误,它只是默默地无法对该属性执行任何操作,并且事件处理程序永远不会运行.)