ViewState 会覆盖 PostBack 上动态添加的 UserControl(在占位符中)的更改

ViewState overwrites changes on dynamically added UserControl (in Placeholder) on PostBack

在我的 ASP.NET 应用程序中 - 启用了 ViewState - 我可以通过简单地再次设置输入来重置输入。这是一个有效的基本简单示例:

_TEST.aspx

<asp:ScriptManager runat="server" />        
<asp:DropDownList ID="ddl" runat="server" DataSource='<%# new string[] { "A", "B", "C" } %>' />
<asp:Button ID="b" runat="server" UseSubmitBehavior="false" OnClick="b_Click" Text="Test 1" />

_TEST.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
  this.DataBind();
  this.ddl.SelectedValue = "B";
}

protected void b_Click(object sender, EventArgs e)
{
  Console.WriteLine("Updated");
}

在此示例中,ddl 将在 Page_Load 上与 "A"、"B" 和 "C" 绑定,并且它将始终 select "B"。因此,当您更改 selection 并提交时,它将被重置。想象一下,这用于在特定条件下重置某些控件。


在我的例子中,我需要在添加到 Placeholder 的动态加载 UserControl 上执行这种行为。因为 Placeholder 不会保留我需要在每次回发时重新创建控件的内容。 ViewState 似乎没问题。这是一个示例:

_TEST.aspx

<asp:ScriptManager runat="server" />
<asp:PlaceHolder ID="ph" runat="server" />

_TEST.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
  _TESTUC uc = (_TESTUC)this.Page.LoadControl("~/Controls/_TESTUC.ascx");
  this.ph.Controls.Add(uc);
}

_TESTUC.ascx

<asp:DropDownList ID="ddl" runat="server" DataSource='<%# new string[] { "A", "B", "C" } %>' />
<asp:Button ID="b" runat="server" UseSubmitBehavior="false" OnClick="b_Click" Text="Test 2" />

_TESTUC.ascx.cs

protected void Page_Load(object sender, EventArgs e)
{
  this.DataBind();
  this.ddl.SelectedValue = "B";
}

protected void b_Click(object sender, EventArgs e)
{
  Console.WriteLine("Updated");
}

同样,在每次回发时我都想重置 DropDownList 的 selection 以进行测试,但有趣的是它会记住我的 selection。

我该怎么做才能解决这个问题?

在写这个问题时,我想到了解决方案,但无论如何还是决定 post 为其他人解决。

似乎 ASP.NET 将在 ASPX 中定义的控件中加载 Page_InitPage_Load 之间的 ViewState,同时加载 ViewState 之间Page_LoadPage_LoadComplete 在代码隐藏中加载的控件中。

设置 Page_LoadComplete 中的值解决了问题:

protected void Page_Init(object sender, EventArgs e)
{
  this.Page.LoadComplete += new EventHandler(this.Page_LoadComplete);
}

protected void Page_Load(object sender, EventArgs e)
{
  this.DataBind();
}

protected void Page_LoadComplete(object sender, EventArgs e)
{
  this.ddl.SelectedValue = "B";
}

protected void b_Click(object sender, EventArgs e)
{
  Console.WriteLine("Updated");
}