10

网络上有大量关于 ASP.NET 生命周期的信息,但我似乎无法弄清楚何时向页面动态添加控件。

一般有两种情况;一个带有母版页的 aspx 页面,一个没有。我目前正在阅读的书(70-515 self prep)说要在 preinit 事件处理程序中向没有母版页的页面添加控件。要动态地将控件添加到内容页面,我应该将该逻辑放在 init 事件处理程序中。

根据 MSDN (http://msdn.microsoft.com/en-us/library/ms178472.aspx) 我应该在 preinit 事件处理程序中创建或重新创建动态控件,并且只读取或初始化 init 事件处理程序中的控件属性(其中对我来说最有意义)。谷歌搜索我看到很多人使用 init 事件处理程序来添加控件。

所以,我在这里有点迷路 - 正确的方法是什么?并且在使用 preinit 事件处理程序时,当所有控件都为空时,如何向页面添加控件?例如,当您需要将动态创建的文本框添加到面板控件时?

亲切的问候,

4

2 回答 2

9

除非您需要在跟踪 ViewState 之前设置控件属性,否则我个人会继续将动态控件添加逻辑放在 OnInit 事件中。

如果您真的想在 PreInit 期间动态添加控件(使用母版页时),您可以随时执行以下操作:

protected override void OnPreInit(EventArgs e)
{
    base.OnPreInit(e);

    TextBox textBox = new TextBox();
    textBox.Text = "Dynamic TextBox";
    textBox.Width = 100;
    textBox.ReadOnly = false;

    var master = this.Master;

    plcHolder.Controls.Add(textBox);
    textBox.ApplyStyleSheetSkin(this.Page);

}

访问“Master”属性将实例化控件并且它应该可以工作,但是您会得到嵌套的母版页场景(this.Master.Master ...)、更新面板等等。

这可能是相关且有用的:http ://weblogs.asp.net/ysolodkyy/archive/2007/10/09/master-page-and-preinit.aspx

此外,我能想到的一个原因(除了遵循定义的页面生命周期之外)MS 建议我们将动态控件创建的所有逻辑放在 Preinit 事件中,以便我们可以利用主题服务,该服务将自动应用所有可用的皮肤属性对我们来说,在 Init 事件发生之前。

假设您的标记看起来像这样:

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Trace="true" Inherits="_Default" Theme="Test" %>

...

<form id="form1" runat="server">

<div>
<p>
    <asp:TextBox ID="TextBox1" runat="server" TextMode="Password" Text="Control TextBox"></asp:TextBox>
</p>
<p>
    <asp:PlaceHolder ID="plcHolder" runat="server"></asp:PlaceHolder>
</p>

</div>
</form>...

你有这样的皮肤:

<asp:TextBox runat="server" BackColor="Yellow" Wrap="false" Text="Skin property!" > </asp:TextBox>

只需将其添加到您的代码后面:

 private TextBox tb1;
protected override void OnPreInit(EventArgs e)
{
    base.OnPreInit(e);
    tb1 = new TextBox();
    tb1.Text = "PreInit Dynamic TextBox";

    Trace.Write(String.Format("tb1 Wrap Property-> {0}",tb1.Wrap));
    Trace.Write(String.Format("tb1 Text Property-> {0}", tb1.Text));
    Trace.Write("Add tb1 to the placeholder.");
    plcHolder.Controls.Add(tb1);
    Trace.Write(String.Format("tb1 Wrap Property-> {0}", tb1.Wrap));
    Trace.Write(String.Format("tb1 Text Property-> {0}", tb1.Text));
}

protected override void OnInit(EventArgs e)
{
    Trace.Write(String.Format("tb1 Wrap Property-> {0}", tb1.Wrap));
    Trace.Write(String.Format("tb1 Text Property-> {0}", tb1.Text));
    base.OnInit(e);
}



protected void Page_Load(object sender, EventArgs e)
{
    Trace.Write(String.Format("tb1 Wrap Property-> {0}", tb1.Wrap));
    Trace.Write(String.Format("tb1 Text Property-> {0}", tb1.Text));

}

您会注意到在进入 Init 事件之前,所有皮肤属性都已应用于动态创建的文本框:)

于 2011-03-21T14:01:26.430 回答
2

PreInit 事件对我来说是新的,但我想它是有道理的,因此您在加载控件和加载视图状态之间有一个中间步骤来做额外的工作。我们使用 init 事件来加载动态控件,这对我们一直有效,没有任何问题。我认为你可以接受,但如果 MS 推荐 PreInit,我会说走那条路。这样,在 Init 中,您可以执行您可能需要的任何其他工作,并将创建 UI 的例程与可能在视图状态加载之前更新它的例程分开。

HTH。

于 2011-01-21T17:47:14.163 回答