我正在使用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;
}
我认为这不重要,但实际渲染发生在updatepanel中,上面的代码位于异步触发的事件处理程序中。我遇到的问题是,在下一个回发中,ViewState["Expandedness"]
返回null。我曾尝试使用Fritz Onion的Viewstate Decoder工具查看回发之间viewstate的实际内容,但它告诉我序列化数据无效。
我在这里采取了错误的做法吗?什么是解决这个问题的正确方法?
答案 0 :(得分: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中存储绝对最少的信息,但是像这样的单个标记很好(实际上是它的设计目的)。
答案 1 :(得分:0)
你什么时候打电话给这个代码?如果在Page_Init中调用它太早了,你对视图状态所做的任何更改都将被忽略。
只是一个想法
答案 2 :(得分:0)
进一步调查:我在子控件事件处理程序中对Viewstate所做的更改与Page_Prerender一样长(即在页面的事件生命周期中稍后),所以问题不在于Viewstate没有得到写给。但是对页面的任何后续回发 - 同步或异步 - 都不会在viewstate中显示该值。