11

我正在尝试创建一个网页,该网页将根据下拉列表的选定值显示适当的用户控件。

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

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

I have it half working... the controls are changing when the selection changes. 在 OnInit() 中,我动态创建最后一个选定的控件(其值保存在会话状态中,因为 ViewState 在 OnInit 中不可用)。

当下拉选择发生变化时,我删除了旧的用户控件,并添加了一个新控件。 问题是:从 selection changed 事件中添加了新控件,我无法在第一次回发时保存用户的更改。第一次回发后,从 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

4 回答 4

11

您需要做的是在 Session 中保留 DropDownList 的最后一个已知值。然后:

初始化:

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

SelectionChanged 事件

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

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

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

于 2009-06-12T16:44:01.927 回答
6

这是 ASP.Net 网络表单的经典问题。你有几个选择:

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

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

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

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

于 2009-06-12T16:44:31.490 回答
1

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

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

于 2009-06-12T17:40:34.943 回答
-4

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

于 2009-06-12T16:41:33.383 回答