我有一个ASP.NET页面,其中包含一个名为ReportCtrl的用户控件(我自己的控件与报表服务等无关)。 ReportCtrl有一个名为TreeViewCtrl的用户控件,它包含一个带有一些时髦的业务逻辑的Telerik TreeView来显示节点。
TreeView放在ASP.NET AJAX面板中。当用户单击可检查节点时,它会回发到服务器并将新的Mapping对象(标记为Serializable)保存到存储在ViewState中的List中。
我遇到的问题是: -
我已经覆盖了检查ViewState中的项目数,我可以看到当选中第二项时,SaveViewState正在保存包含3个项目的ViewState。当在第三个复选框上调用LoadViewState时,我可以看到解码的ViewState中只有1个项目。
protected override void LoadViewState(object savedState)
protected override object SaveViewState()
不知何故,Viewstate仅适用于1个项目,仅适用于FIRST项目。
我们已经确认这与Telerik TreeView无关,只需删除它,只需在按钮点击事件上手动添加项目即可。我们还通过存储字符串列表来消除对象。
我们对于尝试什么的想法很新鲜。有没有人遇到过这个问题?我们可以尝试任何想法吗?
感谢。
CODE
以下是UpdatePanel的代码:
<asp:UpdatePanel runat="server" ID="upnlTreeView" ChildrenAsTriggers="true"
RenderMode="Inline" UpdateMode="Conditional" EnableViewState="true">
<ContentTemplate>
<telerik:RadAjaxManager runat="server" ID="RadAjaxManager1">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="RadAjaxManager1">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="ClickedNodeLabel" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
<telerik:RadTreeView ID="RadTreeView1" runat="server" Width="100%" Height="420px"
PersistLoadOnDemandNodes="true" LoadingStatusPosition="BelowNodeText" CausesValidation="false"
OnClientNodePopulated="nodePopulated" OnClientNodePopulating="nodePopulating" OnClientLoad="onLoad"
CheckBoxes="true" CheckChildNodes="false" AllowNodeEditing="false" MultipleSelect="false"
LoadingMessage="Loading..." AppendDataBoundItems="true" Skin="Vista" EnableViewState="true"
onnodecheck="RadTreeView1_NodeCheck" >
<ExpandAnimation Type="none" />
<CollapseAnimation Type="none" />
<WebServiceSettings Path="/ESConsole/ws/PTService.asmx" Method="GetNodes" />
</telerik:RadTreeView>
</ContentTemplate>
以下是代码背后的List定义和其他方法的代码:
public List<ECodeMapping> ECodeMappings
{
get
{
return (ViewState["__lstECodeMapping"] == null) ? new List<ECodeMapping>()
: ViewState["__lstECodeMapping"] as List<ECodeMapping>;
}
set { ViewState["__lstECodeMapping"] = value; }
}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
int count1 = (ViewState["__lstECodeMapping"] as List<ECodeMapping>).Count;
}
protected override object SaveViewState()
{
int count1 = (ViewState["__lstECodeMapping"] as List<ECodeMapping>).Count;
return base.SaveViewState();
}
protected void RadTreeView1_NodeCheck(object sender, RadTreeNodeEventArgs e)
{
RadTreeNode node = e.Node;
int iLevel = node.Attributes["Level"].ToSafeInt();
if (iLevel == 2)
{
var nList = ECodeMappings.FindAll(x => x.DocId == node.Value.ToSafeInt() && x.SecId < 1);
if (nList.Count() == 0 && node.Checked == true)
{
// Add the node if it doesn't exist
ECodeMapping newMapping = new ECodeMapping { ReportId = ReportId, DocId = node.Value.ToSafeInt(), SecId = int.MinValue };
ECodeMappings.Insert(0, newMapping);
return;
}
答案 0 :(得分:0)
UpdatePanel实际上是将ViewState发送到服务器并在更新时替换当前的ViewState吗?使用Fiddler或类似工具查看实际的HTTP流量。我猜你没有收到所有更新的ViewState。
答案 1 :(得分:0)
发现问题。
我们在父用户控件中有一个脚本,如下所示: -
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequest);
var postBackElement;
function EndRequest(sender, args) {
if (postBackElement.id == '<%= btnUpload.ClientID %>')
var uprog1 = $get('<%= this.UpdateProgress1.ClientID %>');
if(uprog1 != null)
{
uprog1.style.display = 'none';
}
$find('<%= mpeProgress.ClientID %>').hide();
}
此违规脚本必须更改为以下内容: -
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequest);
var postBackElement = null;
function EndRequest(sender, args) {
if (postBackElement != null && postBackElement.id == '<%= btnUpload.ClientID %>')
var uprog1 = $get('<%= this.UpdateProgress1.ClientID %>');
if(uprog1 != null)
{
uprog1.style.display = 'none';
}
$find('<%= mpeProgress.ClientID %>').hide();
}
需要检查postBackElement是否为空。