它的工作方式是控件还呈现隐藏的输入,并且AJAX请求的结果存储在隐藏的输入中.这是回发的,控件的LoadPostData()方法查找隐藏的输入,如果隐藏的输入有数据,则从中创建ListItem集合.
只要用户从列表框中进行选择,这就完美地工作.如果没有,则不会调用LoadPostData()方法,因此不会创建新的ListItem集合. (我已经使用调试器建立了这个.)
我假设只有在POST数据集合包含与控件的UniqueID相对应的数据(即HTML中的“name”属性)时才调用LoadPostData方法.如果用户尚未从列表框中进行选择,则列表框的UniqueID和LoadPostData()的发布数据中不包含任何内容.那是对的吗?
任何人都可以建议我如何确保每次回发都调用我的自定义ListBox的LoadPostData()方法,无论用户是否进行了选择?
提前谢谢 – 我真的很喜欢这个.
大卫
解决方法
我的控件是一个使用模板的树.我正在处理的问题是如何捕获客户端对节点的展开/折叠状态的更改.最终工作的是:
在CreateChildControls中,将隐藏字段添加到我的根控件的控件集合中.
protected override int CreateChildControls(IEnumerable dataSource,bool dataBinding) { ... _cdExpanded = new HiddenField(); _cdExpanded.ID = "cdExpanded"; this.Controls.Add(_cdExpanded); ... }
在OnInit调用中
protected override void OnInit(EventArgs e) { ... Page.RegisterRequiresPostBack(this); ... }
在LoadPostData中,在post集合中查找与隐藏字段的UniqueID(而不是ClientID)匹配的值:
public bool LoadPostData(string postDataKey,System.Collections.Specialized.NameValueCollection postCollection) { ... string cdExpanded = postCollection[_cdExpanded.UniqueID]; ... }
在各个节点的类中,我有代码,它通过调用JavaScript函数来填充我的切换按钮的onclick事件,该函数将基本控件的ID和各个节点作为参数.
string ToggleScript { get { return "ToggleNode('" + this.ClientID + "','" + _TreeRoot.ClientID + "');"; } } protected override void Render(HtmlTextWriter writer) { ... if (this.HasChildren) { writer.AddAttribute("onclick",ToggleScript); } ... }
这使得通过getElementById找到隐藏字段相当容易:
function ToggleNode(nodeID,treeID) { var cdExpanded = document.getElementById(treeID + "_cdExpanded"); ... }
然后JavaScript根据发生的事件需要修改隐藏字段的值.当我们回到服务器时,我能够解析出该字段的内容,并在再次呈现之前根据需要修改控件状态. (注意:我实际上使用3个隐藏字段来跟踪不同的事件,但概念是相同的)
希望这对未来的其他人有所帮助……