如果通过LoadControl(ctr)加载UserControl.ascx,则事件不起作用

时间:2011-07-07 21:57:30

标签: asp.net page-lifecycle

我发现这是一个有趣的小问题。我认为原因在于页面对象/事件生成的生命周期,但问题是我如何解决问题?

在Default.aspx中存在一些有趣的控件但也有一个 <asp:PlaceHolder runat="server" id="phUserContent"></asp:PlaceHolder>

此占位符在运行时为空。在某些情况下,代码隐藏在将UserControls加载到其中。像这样 Control ctr = LoadControl("~/UserControl/Note.ascx"); phUserContent.Controls.Add(ctr);

这个Note.ascx包含一些有趣的控件,最后是一个触发事件的LinkBut​​ton。 LinkBut​​ton代码非常简单且格式正确,
<asp:LinkButton runat="server" ID="lbUpdate" OnClick="lbUpdate_Click" Text="Update"></asp:LinkButton>

在ascx背后的代码中我有事件的代码,

protected void lbUpdate_Click(object sender, EventArgs e)
{ ... }

正如我所想的那样,回发发生,页面会重新生成,因为我怀疑 - 但没有执行lbUpdate_Click事件。当然可以尝试一个断点。

我正在寻找两种可能的情景。一个是我错过了一些非常容易的东西(你知道,就像错误的代码背后的错误)或者我错过了页面生成周期的重要部分。

我大部分都是第二个,就像这样(我只是想在这里......)
1. Page(ascx)得到了改变 2.单击提交 3.重新生成了Ascx 事件被清除但存在并且没有投射错误。 5.重新加载后,重新加载初始内容

结果是编译器无法看到断点,并且由于“执行空事件”而从未保存过值。但这只是一个业余猜测,请建议我。

[根据答案更新] 根据下面的通道答案,我就是这样解决的。

List<Control> ctr;
public User()
{
    ctr = new List<Control>();
}
protected void Page_PreInit(object sender, EventArgs e)
{
    ctr.Add(LoadControl("~/UserControl/Note.ascx"));
}

protected void Page_Load(object sender, EventArgs e)
{
    ctr.ForEach(d => phUserContent.Controls.Add(d));
}

很快..
这个班得到了一份控制清单 2.在Page_PreInit(创建之前)添加UC(你可以在这里使用X) 3.在Page_Load(创建所有ctr的地方)中,将每个UC添加到PH。

这也使得UC中的事件也起作用,没有魔法和没有愚蠢的并发症: - )

1 个答案:

答案 0 :(得分:2)

这是一个生命周期问题。

请记住,每个页面请求都会创建一个页面对象,并在其上创建所有控件的 new 实例。如果您正在动态创建控件,则必须在每次回发时以完全相同的方式完成控件。如果您希望新控件触发事件,则它必须具有与旧事件相同的ID,并在生命周期中处理控制事件之前将事件连接到它。

如果您在处理ViewState之后的页面生命周期中的某个点动态创建控件,那么您还必须管理自己的状态。换句话说,如果您在PreInit阶段没有动态创建控件,那么您将不得不手动处理恢复状态。