我理解事件发生在页面生命周期中的顺序,但它对我的情况没有帮助。我有一个复选框列表,由一个填充表单的目录填充。当我选中表单名称旁边的框时,我希望它动态创建向导步骤并插入表单。
活动顺序: 是OnInit: GatherForms() - 检查目录并将所有表单名称加载到复选框中 LoadForms() - 检查“已选择”会话并加载已收集的表单
CheckBoxList:SelectedIndexChanged #AutoPost = true# PopulateForms() - 遍历复选框并将它们添加到会话状态
当用户单击该复选框时,它会进行回发并点击从会话中提取的OnInit。问题是PopulateForms()还没有运行,因此即使检查它也没有填充任何内容。如果我点击另一个项目,它将回发并显示。在刷新之前,我似乎无法从复选框中提取任何有用的信息,这意味着我无法立即看到表单。我也试过循环复选框但不幸的是viewstate尚未发布。叹息。
有什么建议吗?
谢谢!
P.S:我不能使用Request.Form [],因为我必须从复选框中取出所有选定的项目。也许我可以,但我找不到方法:/
答案 0 :(得分:1)
仅在OnInit中添加动态控件。在PageLoad之前不要进行任何人口/处理。您将以这种方式保留您的价值观。
答案 1 :(得分:1)
当我在ASP.NET上做得更好时,这是我遇到的一个常见问题。
使用动态控件时,您会遇到OnInit期间实际不存在的问题。
您可以做的是创建用户在OnInit期间可能看到的控件的所有,并隐藏用户在代码中看不到的元素。页面将加载,所有可能的控件都将被实例化(在代码中 - 不要担心这出现在HTML中并使其膨胀),然后事件处理程序将触发,然后您可以处理设置向导的可见性。 / p>
例如:
public void OnInit(object sender, EventArgs e)
{
GatherForms();
CreateWizardForm(); // creates a wizard and adds controls it will need
}
private void Checkbox_Checked(object sender, EventArgs e)
{
var checkBox = (CheckBox)sender;
// append checkBox.SelectedValue to session state object of checkboxes
}
protected override void OnPreRender(object sender, EventArgs e)
{
if (/* Session checkboxes contain values */)
{
this.WizardForm.Visible = true;
this.CheckboxList.Visible = false;
}
}
如果您提前知道哪些控件将以向导形式提供,则此工作正常。你可以在OnPreRender事件中更改这些控件的值,切换它们的可见性等,但是你不能去添加新的控件(例如Controls.Add(new Button())) - 这必须在OnInit中完成事件
答案 2 :(得分:0)
动态控制的经典陷阱。
老实说,最好的解决方案是使用Request
值数组来查找所需的信息,并忽略这种特定情况下的生命周期内容。
在OnInit()
中,已发布的值已存在,但尚未由ViewState处理。因此,您可以if (Request["myCheckBoxName"] == xxx)
处理单个复选框,或者如果您可以使用Request["__EVENTTARGET"]
获取导致回发的控件名称。
请参阅我的旧答案here,以便对此问题进行更全面的讨论。