网上有关于ASP.NET生命周期的大量信息,但我似乎无法弄清楚何时动态地向页面添加控件。
一般情况下有两种情况;一个包含母版页的aspx页面,另一个没有。我正在阅读的这本书(70-515自我准备)说要在preinit事件处理程序中为没有母版页的页面添加控件。要动态地将控件添加到内容页面,我应该将该逻辑放在init事件处理程序中。
根据MSDN(http://msdn.microsoft.com/en-us/library/ms178472.aspx)我应该在preinit事件处理程序中创建或重新创建动态控件,并且只读取或初始化init中控件的属性eventhandler(这对我来说最有意义)。谷歌搜索我看到很多人使用init eventhandler来添加控件。
所以,我在这里有点迷失 - 这是正确的方法吗?当使用preinit事件处理程序时,如果所有控件都为null,如何在页面中添加控件?例如,当您需要将动态创建的文本框添加到面板控件时?
亲切的问候,
答案 0 :(得分: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事件之前,所有皮肤属性已经应用于动态创建的文本框:)
答案 1 :(得分:2)
PreInit事件对我来说是新的,但我认为这是有道理的,因此您在加载控件和视图状态加载之间有一个中介步骤来执行其他工作。我们使用init事件来加载动态控件,这对我们来说一直没有问题。我想你也可以,但如果MS推荐PreInit,我会说走那条路。这样,在Init中,您可以执行您可能需要的任何其他工作,并将创建UI的例程与可能在视图状态加载之前更新它的例程分开。
HTH。