免责声明:我已阅读the ASP.net page life cycle,并且我还阅读了与动态控件相关的several good articles,但我必须遗漏一些内容。
背景:我目前正在开发一个网站,需要根据用户的输入创建大量动态内容。我理解,为了使动态控件保持不变并使其事件正确连接,我需要在每个页面上重新创建这些动态控件。
由于我的项目的性质,我的代码不知道要创建什么控件,除非它有一些关于用户选择的信息。我将用户的选择存储在ViewState
中,Page_Init
中不可用,因为它尚未加载。因此,我必须等到Page_PreLoad
或Page_Load
才能阅读ViewState,然后重新创建动态控件。
我不理解的部分:当我尝试在Page_Load
期间重新创建控件时,控件仍然存在,但相关事件似乎没有触发。例如,单击我创建的LinkButton
不会触发我连接到其Click
事件的方法,即使按钮本身仍然存在。
我偶然发现的一个奇怪的解决方案是,我可以在Page_PreLoad
期间重新创建控件,然后事件正确触发。
我的问题(或问题,而不是):为什么我的问题似乎在Page_PreLoad
而不是Page_Load
期间重新创建控件时消失了?这是安全的做法吗?我从未见过使用Page_PreLoad
的任何其他代码,这让我很谨慎。这个解决方案对我有用,但是我有什么陷阱可能会丢失吗?我是否在不知不觉中为自己以后的失败做好准备?
我的代码,其中LoadDocument()
是一种创建控件并将其填充到静态Panel
控件中的方法:
protected void Page_PreLoad(object sender, EventArgs e)
{
if (ViewState["xmlfilename"] != null)
{
LoadDocument(ViewState["xmlfilename"].ToString());
}
}
答案 0 :(得分:1)
您的活动将在ProcessPostData
期间处理。哪个控件触发回发也是发布数据。如果您的控件当时不存在,则不会收到该事件。
我同意Init
太早,Load
太晚了。
您需要做的是在加载视图状态后立即创建这些控件。
页面生命周期中没有此事件。但是,所有函数都是虚函数,您可以覆盖之间调用的函数。
加载依赖于ViewState中存储的值的控件的最佳位置是LoadViewState
函数。
现在所有控件事件都应该正常启动。
答案 1 :(得分:1)
可能你读过我对这个主题的一个答案:
我可以告诉你,我使用PreLoad
事件生成代码并且工作正常
但对于新开发,我使用Init
事件,为什么?因为它是微软的推荐,因此它可以被视为一种标准,并且技术优势如ViewState的自动加载,主题支持和最重要的(从我的观点来看),动态控件事件是同步的静态控件。
您的问题是正确的,在Init
事件中尚未加载ViewState,但这并不会阻止您访问Form
集合
我创建了一个用于学习目的的页面,我在按需创建动态控件,我在Init
事件中执行此操作。我正在创建TextBoxes
,并且在每个帖子中,当文本发生更改时,他们会提升TextChanged
事件。
注意:在继续之前,我想提醒您ViewState已加载匹配控件的ID ,这就是为什么使用相同的ID重新创建动态控件的好习惯
这是代码:
<asp:HiddenField runat="server" ID="numberOfDynamicControls" Value="0" />
<asp:Panel runat="server" ID="myPanel">
</asp:Panel>
<asp:Button Text="Add Control" runat="server" ID="addControl" OnClick="addControl_Click" />
<asp:Label ID="lblMessage" runat="server" />
protected void Page_Init(object sender, EventArgs e)
{
this.CreateDynamicControls();
}
protected void addControl_Click(object sender, EventArgs e)
{
var n = int.Parse(this.numberOfDynamicControls.Value);
n++;
this.numberOfDynamicControls.Value = n.ToString();
this.myPanel.Controls.Add(this.CreateTextbox(n));
}
private void CreateDynamicControls()
{
int n = 0;
if (!string.IsNullOrWhiteSpace(this.Request.Form["numberOfDynamicControls"]))
{
n = int.Parse(this.Request.Form["numberOfDynamicControls"]);
}
for (int i = 0; i < n; i++)
{
var t = this.CreateTextbox(i + 1);
t.TextChanged += (x, y) => this.lblMessage.Text += "<br/>" + (x as TextBox).ID + " " + (x as TextBox).Text;
this.myPanel.Controls.Add(t);
}
}
private TextBox CreateTextbox(int index)
{
var t = new TextBox { ID = "myTextbox" + index.ToString(), Text = "de" };
return t;
}