首页 > 解决方案 > Dynamically created form values persisting after postback

问题描述

I have a usercontrol which contains dynamically generated webcontrols (TextBox, DropDownList, etc...)

The usercontrol is loaded on certain button click events.

On the usercontrol, there are occasionally postback events which need to be processed (Button.OnClick, etc...).

In order to accommodate the fact that the usercontrol is loaded on a click event, during Page_Load() of the usercontrol's parents, I'm re-executing the code that loads the usercontrol.

IE - I have, essentially, the following:

public partial class parentPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        If(Page.IsPostBack)
        {
            // Conditions are usually here to make sure this only happens when I want it to
            userControl.LoadUserControl();
        }
    } 

    protected void Button_Click(object sender, EventArgs e)
    {
        userControl.LoadUserControl();
    }
}

public partial class userControl : System.Web.UI.UserControl
{
    public void LoadUserControl()
    {
        // Generate dynamic controls and bind events
    }

    protected void Button_Click(object sender, EventArgs e)
    {
        // Do stuff
    }
}

The problem I'm facing is that, after the Button_Click() event of the usercontrol is processed, the next time I click the button on the parent, the usercontrol's dynamically generated fields are somehow being automatically populated by what they were before the usercontrol's button was clicked - despite the fact that I'm explicitly setting the values when the LoadUserControl() function is called during the parent's button click.

What's even stranger is that the fields which are populated aren't necessarily consistent. In some cases TextBoxes have the correct text but DropDownLists have the old selected item. In other cases, DropDownLists are properly selected, but the TextBoxes retain the old text.

Does anyone have any suggestions or insights? I've tried a million different ideas and nothing seems to work.

** EDIT **

A bit of insight, perhaps - if I set the usercontrol to ViewStateMode=Disabled, it seems to solve the problem. I am reluctant to do this though, as I'm really not sure whether it will affect other functionality. I've already discovered a few glitches with the change, and I've a feeling even if I fix those, I'll end up finding more later. So hopefully any solution will not require such a drastic change. Perhaps the fact that it does solve this problem may help find a more elegant solution, though?

** EDIT 2 **

Debugging using dotPeek into the framework for System.Web.UI.ControlCollection.Add() reveals that, after adding the control to the collection, System.Web.UI.Control.AddedControl() is called. At the end of that, System.Web.UI.Control.LoadViewStateRecursive() is called. It's within there that the trouble arises. Despite the fact that this is a dynamically generated control, it still seems to persist in the ViewState. Continuing to dig...

标签: .netdynamicuser-controlspostback

解决方案


好吧!经过两天对 .NET Framework 的深层、黑暗内部的调试,我终于找到了一个解决方案。

我仍然不确定为什么会发生这个问题,但解决方案是禁用我想要手动加载的控件的 ViewState,但仅限于初始加载。

由于控件的加载是在 Postback 上进行的,所以我不能使用简单的 if(!Page.IsPostBack) 选项,所以我确实使用了一个我已经编写的函数,它返回的 Postback Control ID控制执行回发。如果 ID 与我知道最初用于加载控件的按钮匹配,那么在创建不同的输入时,我将它们的 ViewStateMode 设置为 Disabled,并且为了获得奖励积分,还将 EnableViewState 设置为 false。

关键是,当这些控件执行它们自己的回发(IE、DropDownList.SelectedIndexChanged、Button.Click 等)时,它们的 ViewStateMode 已启用 - 所以一切正常!


推荐阅读