ASP.Net:为什么不';我在控件事件中对Viewstate所做的更改是否可用于后续回发?

ASP.Net:为什么不';我在控件事件中对Viewstate所做的更改是否可用于后续回发?,asp.net,asp.net-ajax,viewstate,Asp.net,Asp.net Ajax,Viewstate,我正在使用ASP.NETAJAX在ASP.NET3.5WebForms中编写一个自定义控件。我正在控件中构建一个状态切换(展开和折叠模式)。我一直试图将控件的当前状态保持在ViewState中,并在服务器端事件处理程序中手动更改它: object oExpanded = ViewState[ "Expandedness" ]; if(oExpanded == null) { oExpanded = ListState.Collapsed; } ListState lsCurrentSta

我正在使用ASP.NETAJAX在ASP.NET3.5WebForms中编写一个自定义控件。我正在控件中构建一个状态切换(展开和折叠模式)。我一直试图将控件的当前状态保持在ViewState中,并在服务器端事件处理程序中手动更改它:

object oExpanded = ViewState[ "Expandedness" ];
if(oExpanded == null)
{
    oExpanded = ListState.Collapsed;
}
ListState lsCurrentState = (ListState) oExpanded;
if(lsCurrentState == ListState.Collapsed)
{
    //code snipped - move to expanded mode here
    ViewState[ "Expandedness" ] = ListState.Expanded;
}
else
{
    //code snipped - move to collapsed mode here
    ViewState[ "Expandedness" ] = ListState.Collapsed;
}
我认为这不重要,但实际的呈现发生在updatepanel中,上面的代码在异步触发的事件处理程序中。我遇到的问题是,在下一次回发时,
ViewState[“Expandedness”]
返回null。我曾尝试使用Fritz Onion的Viewstate解码器工具查看回发之间Viewstate的实际内容,但它告诉我序列化的数据无效


我是不是走错了路?解决此问题的正确方法是什么?

您何时调用此代码?如果在Page_Init中调用它,则为时过早,并且您对viewstate所做的任何更改都将被忽略


只是想一想

您何时调用此代码?如果在Page_Init中调用它,则为时过早,并且您对viewstate所做的任何更改都将被忽略


只是一个想法

进一步的调查:我在子控件事件处理程序中对Viewstate所做的更改会持续到Page_Prerender(即,在页面的事件生命周期的后期),因此问题不是Viewstate没有写入。但是对页面的任何后续回发(同步或异步)都不会在viewstate中显示该值。

进一步调查:我在子控件事件处理程序中对viewstate所做的更改会持续到页面预呈现的时间(即页面事件生命周期的后期),所以问题不在于Viewstate没有被写入。但是任何后续对页面的回发(同步或异步)都不会在viewstate中显示该值。

您是对的,它可以在UpdatePanel中显示,这不会有任何区别

我怀疑您的控件或其父控件禁用了ViewState:如果任何父控件(一直到页面)禁用了ViewState,则您的控件将禁用ViewState

要解决这个问题,可以使用页面的ViewState字典,而不是控件上的字典

也就是说,不要说:

this.ViewState[ "Expandedness" ] = ListState.Expanded;
说:

如果页面上可能有多个控件实例,则需要确保ViewState键是唯一的,可能如下所示:

this.Page.ViewState[ this.ClientID + "Expandedness" ] = ListState.Expanded;

作为替代方案(即使VIEWSTATE对页禁用)也可以工作,您可以考虑将扩展性存储在控件状态中。这有点棘手,但谷歌一下,你会很快找到一个代码示例。建议您在ControlState中只存储绝对最少的信息,但是像这样的单个标志是可以的(实际上它是为什么而设计的)。

您是对的,它可以放在UpdatePanel中-这不会有任何区别

我怀疑您的控件或其父控件禁用了ViewState:如果任何父控件(一直到页面)禁用了ViewState,则您的控件将禁用ViewState

要解决这个问题,可以使用页面的ViewState字典,而不是控件上的字典

也就是说,不要说:

this.ViewState[ "Expandedness" ] = ListState.Expanded;
说:

如果页面上可能有多个控件实例,则需要确保ViewState键是唯一的,可能如下所示:

this.Page.ViewState[ this.ClientID + "Expandedness" ] = ListState.Expanded;

作为替代方案(即使VIEWSTATE对页禁用)也可以工作,您可以考虑将扩展性存储在控件状态中。这有点棘手,但谷歌一下,你会很快找到一个代码示例。建议您在ControlState中只存储绝对最少的信息,但是像这样的单个标志是可以的(实际上是它的设计目的)。

好主意,但是这段代码是在子控件的事件处理程序中调用的(因此,就生命周期而言,它发生在Page_加载之后和Page_预呈现之前)。所以我应该有权访问Viewstate。好主意,但这段代码是在子控件的事件处理程序中调用的(因此,在生命周期方面,它发生在页面加载之后和页面预呈现之前)。所以我应该可以访问Viewstate。这正是导致它的原因!我错过了页面本身的
EnableViewState=“false”
。谢谢你,提迪!这正是导致它的原因!我错过了页面本身的
EnableViewState=“false”
。谢谢你,提迪!