动态更改ASP.Net中的用户控件

时间:2009-06-12 16:34:31

标签: asp.net dynamic-controls

我正在尝试创建一个网页,根据所选的下拉列表值显示相应的用户控件。

基本上页面布局是这样的:

下拉选择
< 基于下拉选择创建的用户控件 >

我有一半工作...当选择改变时控件正在改变。 在OnInit()中,我动态创建最后选择的控件(其值以会话状态保存,因为OnInit上没有ViewState)。

当下拉选择更改发生时,我删除旧的用户控件,并添加一个新的用户控件。 问题是:从选择更改事件中添加新控件后,我无法在第一次回发时保存用户的更改。在第一篇回发后,从OnInit而不是Change事件创建所选控件,然后保存状态,直到下一次选择更改。

这是SelectionChanged方法:

protected void SelectionChanged(object sender, EventArgs e)
{
    SelectedValue = int.Parse(DropDownList.SelectedValue);  //Store in Session
    Control userControl = GetSpecificUserControl(SelectedValue);
    PlaceHolder1.Controls.Clear();   // Remove old user control
    PlaceHolder1.Controls.Add(userControl);
}

在SelectionChanged发生后,用户对新控件所做的任何更改都不会保存在以下帖子中。但是,随后的回发会得到保存。此时,控件将在OnInit()中创建。

当控件发生变化时,是否有某种方法强制正确回发和ViewState?控件更改后是否可以强制页面重新初始化?

4 个答案:

答案 0 :(得分:10)

您需要做的是在会话中保留DropDownList的最后已知值。然后:

<强>的OnInit:

  • 创建会话中保存的值所指示的任何控件

SelectionChanged事件

  • 删除在OnInit期间创建的任何内容
  • 根据新的DropDownList选择创建并添加新控件
  • 在会话中保存新的DropDownList选择

这样,在更改后的下一个回发中,您将重新创建ViewState期望找到的控件,因此它的状态将被恢复。

动态控件非常挑剔。通常,创建可能需要的所有控件并将其Visible属性设置为false更容易。这样它们根本不会呈现给浏览器。然后将Visible设置为true,只需在需要时控制所需的控件。

答案 1 :(得分:5)

这是ASP.Net webforms的经典撕裂问题。您有几种选择:

1)这有点像黑客,因为它超出了预期的页面生命周期,但根据我的经验,这是处理问题的最直接方式。当页面从下拉选择事件发回时,只需在Request["MyDropDownID"]期间轮询Init()下拉控件的选定值 - 不要等待OnMyDropDownChanged()事件设置你的页面。

2)为您的用户控件实现自己的ViewState处理。这需要深入研究ViewState文档并覆盖许多方法。

3)Joel的解决方案。他打败了我,但我试图获得第一篇文章:p

其他选项涉及使用javascript等发布值,但那些会变得非常混乱。

答案 2 :(得分:1)

如果选项列表不是太大,您可以静态渲染所有用户控件,并使用JavaScript / jQuery根据下拉列表的值显示/隐藏相应的控件(onchange js事件)。保存时,您可以使用下拉值从用户控件中提取适当的值。

您可以避免处理动态控件的痛苦,从下拉列表中选择时提供响应更快的UI(无回发)等等。

答案 3 :(得分:-4)

不要在SelectedIndexChanged处理程序中添加控件,在Page_Load期间添加它。您只需在每次加载页面时测试下拉列表的值,并为该值加载正确的控件。