动态创建的表单值在回发后持续存在

Dynamically created form values persisting after postback

我有一个用户控件,其中包含动态生成的 Web 控件(TextBox、DropDownList 等...)

用户控件在某些按钮单击事件上加载。

在用户控件上,偶尔会出现需要处理的回发事件(Button.OnClick,等等)。

为了适应用户控件是在单击事件上加载的事实,在用户控件的父级 Page_Load() 期间,我正在重新执行加载用户控件的代码。

IE - 我基本上有以下内容:

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
    }
}

我面临的问题是,在处理完用户控件的 Button_Click() 事件后,下次我单击父控件上的按钮时,用户控件的动态生成字段会以某种方式自动生成由单击用户控件按钮之前的值填充 - 尽管我在单击父级按钮期间调用 LoadUserControl() 函数时明确设置了值。

更奇怪的是,填充的字段不一定一致。在某些情况下,TextBox 具有正确的文本,但 DropDownList 具有旧的选定项。在其他情况下,DropDownLists 被正确选择,但 TextBoxes 保留旧文本。

有没有人有任何建议或见解?我尝试了一百万种不同的想法,但似乎没有任何效果。

** 编辑 **

也许有点见识-如果我将用户控件设置为ViewStateMode=Disabled,似乎可以解决问题。不过我不愿意这样做,因为我真的不确定它是否会影响其他功能。我已经发现了这个变化的一些小问题,我有一种感觉,即使我修复了这些问题,我最终也会在以后发现更多。因此,希望任何解决方案都不需要如此剧烈的改变。不过,也许它确实解决了这个问题,这可能有助于找到更优雅的解决方案?

** 编辑 2 **

在 System.Web.UI.ControlCollection.Add() 的框架中使用 dotPeek 进行调试表明,在将控件添加到集合后,会调用 System.Web.UI.Control.AddedControl()。在 that 的末尾,调用 System.Web.UI.Control.LoadViewStateRecursive()。问题就在里面。尽管这是一个动态生成的控件,但它似乎仍然存在于 ViewState 中。继续挖掘...

好的!在对 .NET Framework 的深层、黑暗内部进行了两天的调试之后,我终于找到了解决方案。

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

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

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