C# Viewstate变量在动态加载的用户控件上丢失

C# Viewstate变量在动态加载的用户控件上丢失,c#,asp.net,user-controls,C#,Asp.net,User Controls,我对ViewState有问题。我有一个aspx页面,左边有一个treeview,右边有一个UpdatePanel,里面有一个ASP.NET面板。它位于我动态加载和卸载用户控件的内部面板中。我使用更新面板动态加载控件 我还为我的用户控件创建了一个自定义控件,因为我需要从页面传递一些值。在该构造函数上,我使用ViewState存储这些值 第一次加载用户控件时,我使用参数调用其构造函数。当我在每次回发上重新加载该用户控件时,我使用它的普通构造函数 我的问题是,我在ViewState上存储的值在连续回发

我对ViewState有问题。我有一个aspx页面,左边有一个treeview,右边有一个UpdatePanel,里面有一个ASP.NET面板。它位于我动态加载和卸载用户控件的内部面板中。我使用更新面板动态加载控件

我还为我的用户控件创建了一个自定义控件,因为我需要从页面传递一些值。在该构造函数上,我使用ViewState存储这些值

第一次加载用户控件时,我使用参数调用其构造函数。当我在每次回发上重新加载该用户控件时,我使用它的普通构造函数

我的问题是,我在ViewState上存储的值在连续回发时变为空

更新:

I load the controls with this code:

System.Web.UI.UserControl baseControl = LoadControl(ucUrl) as System.Web.UI.UserControl;
if (baseControl != null)
{
    baseControl.ID = "DestinationUserControl";
    PanelDestination.Controls.Add(baseControl);
}
这是我的用户控件的一部分:

public class MyUserControl : System.Web.UI.UserControl
{
private int PKId
{
    get { return ViewState["pkId"] as int; }
    set { ViewState["pkId"] = value; }
}

public MyUserControl(int pkId)
{
    this.PKId = pkId;
}

...
}
我将按照本文动态加载控件:

第二次更新:
在第一次加载用户控件和每次重新加载时,我还设置了相同的控件ID


也许我可以使用另一种方法来存储这些值,比如输入隐藏字段或缓存。我选择ViewState是因为我不想用每个用户的会话值使服务器过载

第三次更新:

I load the controls with this code:

System.Web.UI.UserControl baseControl = LoadControl(ucUrl) as System.Web.UI.UserControl;
if (baseControl != null)
{
    baseControl.ID = "DestinationUserControl";
    PanelDestination.Controls.Add(baseControl);
}
并使用此代码重新加载:

DynamicControls.CreateDestination ud = this.LoadControl(TrackedUserControl) as DynamicControls.CreateDestination;
if (ud != null)
{
    ud.ID = "DestinationUserControl";
    PanelDestination.Controls.Add(ud);
}

发生了什么事

在UpdatePanel中动态添加控件是个糟糕的主意。它产生了很多问题


如果可能,将动态控件创建移出UpdatePanel,我相信您的问题会得到解决

何时加载用户控件?如果希望保存/还原ViewState,则必须在Init事件中执行此操作。

如前所述,应在Page_Init而不是Page_load中加载动态控件

如前所述,在Page_Load事件发生时,回发的视图状态已被处理(在预加载中)。如果控件尚未重新加载,则视图状态无处可去

预载:

如果需要执行,请使用此事件 在页面或控件上进行处理 在加载事件之前

在页面实例引发此错误之前 事件,它为自己加载视图状态 和所有控件,然后处理 随附的任何回发数据 请求实例


在将控件添加到控件层次结构之前,尝试在加载/构造控件后将其存储到局部变量中。允许ViewState数据从控件映射到控件。请参阅此处的“规则2”。

请提供一些执行此操作的代码,以便我们更好地了解正在发生的情况。为什么在初始加载时将其键入UserControl,在重新加载时将其键入CreateDestination?顺便说一句,另一种方法是手动将控件的状态保存到ViewState(您可以通过覆盖SaveViewState或在预渲染时将重要状态复制到ViewState中来完成此操作)。回发时,您可以覆盖LoadViewState并将手动保存的状态放入某些类实例字段(或在加载开始时将状态从ViewState传输到动态创建的控件)。我将使用Session而不是ViewState。与动态加载的用户控件相关的某些内容会丢失ViewState变量。很抱歉,我犯了一个错误。它是一个内部带有ASP.NET面板的UpdatePanel。它位于我动态加载和卸载用户控件的内部面板中。用户控件有一些文本框。如果有一些文本,它在回发中被正确还原。我正在Page_Load事件中重新加载用户控件。我跟随这篇文章动态加载控件:如果那篇文章说在Page_Load中加载动态控件,那完全是错误的。这在某些情况下是可行的,但肯定不是所有情况,正如您所发现的。ViewState还原发生在首页加载,这就是为什么变量为空。没有更简单的解释方法。也许我可以使用其他方法来存储这些值,如输入隐藏字段或缓存。我选择ViewState是因为我不想过载服务器。控件可以在加载事件中回发时动态添加,此时它们的生命周期将“赶上”到当前事件。请参见此处的“添加控件的追赶事件”,以及此处的演练6(这很好地说明了将控件添加到层次结构之前和之后的行为差异)。@gWiz,而演练6很有趣,这取决于“追赶”事件,充其量也有问题。就连演练本身也说建议您在“PreInit”或“Init”事件期间添加动态控件“。这就是我向@VansFannel建议的。不要使用PreInit。我在这方面有过不好的经验…就像使用Page_Load一样。我不知道为什么。Init事件绝对是一种方式。也许我不理解你的答案,但我正在以规则2的方式做。我更新了我的问题,并提供了更多细节。