1

我正在使用 ASP.Net AJAX 在 ASP.Net 3.5 WebForms 中编写自定义控件。我正在为控件构建一个状态切换(展开和折叠模式)。我一直在尝试将控件的当前状态保留在 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;
}

我认为这无关紧要,但实际渲染发生在更新面板中,并且上面的代码位于异步触发的事件处理程序中。我遇到的问题是,在下一次回发时,ViewState["Expandedness"]返回 null。我尝试使用 Fritz Onion 的 Viewstate Decoder 工具来查看回发之间 viewstate 的实际内容,但它告诉我序列化数据无效。

我在这里采取了错误的方法吗?解决这个问题的正确方法是什么?

4

3 回答 3

1

你是对的,它可以在 UpdatePanel 中 - 这应该没有任何区别。

我怀疑 ViewState 已为您的控件或其父级之一禁用:如果它为任何父级禁用(一直到页面),它将为您的控件禁用。

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

即而不是说:

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

说:

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

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

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

作为替代方案(即使 ViewState 对页面禁用也可以),您可以考虑将 Expandedness 存储在 ControlState 中。这有点棘手,但谷歌它,你会很快找到一个代码示例。建议您在 ControlState 中仅存储绝对最少的信息,但是像这样的单个标志很好(实际上它的设计目的是什么)。

于 2009-02-24T23:01:13.260 回答
0

你什么时候调用这个代码?如果在 Page_Init 中调用它为时过早,您对视图状态所做的任何更改都将被忽略。

只是一个想法

于 2009-02-24T22:41:39.173 回答
0

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

于 2009-02-24T23:01:07.100 回答