ASP.NET / C#混淆动态创建的控件

时间:2011-03-24 14:42:35

标签: asp.net dynamic-controls

我一直在使用默认的ASP.NET Web应用程序模板,以下代码抛出异常:

  

对象引用未设置为   对象的实例。

单击创建的按钮时

有人可以提供技术解释吗?

注1:标记只是一个空白页面,里面有占位符 - 见下文。

注2:将Button替换为LinkButton,代码不会抛出异常并起作用。

public partial class test : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        foo();
    }
    protected override void OnLoad(EventArgs e)
    {
        foo();
    }
    protected void foo()
    {
        placeholder1.Controls.Clear();
        placeholder1.Controls.Add(new Button() { Text = "test", ID = "btn" });
    }
}

标记:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test.aspx.cs" Inherits="WebApplication1.test" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:PlaceHolder runat="server" ID="placeholder1" />
    </div>
    </form>
</body>
</html>

3 个答案:

答案 0 :(得分:0)

看起来像placeholder1或placeholder1.Controls为null。这是给出代码示例的NullReferenceException的唯一解释。

答案 1 :(得分:0)

我的猜测是,一旦从后面回来,该按钮为空。您基本上是删除按钮并创建一个新按钮,可能会删除相关事件。

为了支持我的理论,我试过这个:

protected override void OnInit(EventArgs e)
{
    if (!IsPostBack)
        foo();
}
protected override void OnLoad(EventArgs e)
{
    if (!IsPostBack)
        foo();
}
protected void foo()
{
    placeholder1.Controls.Clear();
    placeholder1.Controls.Add(new Button() { Text = "test", ID = "btn" });
}

并没有收到您收到的错误。

为什么要在运行时添加按钮?

答案 2 :(得分:0)

如果从OnLoad()中删除对foo()的调用,我认为代码将开始工作。

原因是页面生命周期中的事件顺序。为了使控件能够引发事件,需要在ProcessPostData(),RaiseChangedEvents()和RaisePostBackEvents()事件发生之前创建控件(有关页面生命周期的图形表示,请参阅http://www.eggheadcafe.com/articles/o_aspNet_Page_LifeCycle.jpg)事件是在OnInit()之后但在OnLoad()

之前引发的

当你的代码在OnLoad()中调用foo()时,你会破坏在OnInit()中调用foo()时创建的实例,所以当引发Event时,引发它的控件不再存在因此“对象引用未设置为实例”消息。