Dav*_*vid 7 asp.net viewstate postback custom-controls postdata
我开发了一个扩展ListBox的自定义控件.这个想法是控件"记住"对客户端发生的元素的修改,例如由于AJAX请求.
它的工作方式是控件还呈现隐藏的输入,并且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);
...
}
Run Code Online (Sandbox Code Playgroud)
在OnInit调用中
protected override void OnInit(EventArgs e)
{
...
Page.RegisterRequiresPostBack(this);
...
}
Run Code Online (Sandbox Code Playgroud)
在LoadPostData中,在post集合中查找与隐藏字段的UniqueID(而不是ClientID)匹配的值:
public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
{
...
string cdExpanded = postCollection[_cdExpanded.UniqueID];
...
}
Run Code Online (Sandbox Code Playgroud)
在各个节点的类中,我有代码,它通过调用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);
}
...
}
Run Code Online (Sandbox Code Playgroud)
这使得通过getElementById找到隐藏字段相当容易:
function ToggleNode(nodeID, treeID) {
var cdExpanded = document.getElementById(treeID + "_cdExpanded");
...
}
Run Code Online (Sandbox Code Playgroud)
然后,JavaScript根据发生的事件的需要修改隐藏字段的值.当我们回到服务器时,我能够解析出该字段的内容,并在再次呈现之前根据需要修改控件状态.(注意:我实际上使用3个隐藏字段来跟踪不同的事件,但概念是相同的)
希望这对未来的其他人有所帮助......
我已经确定,除非发布数据包含与控件的 UniqueID 同名的项目,否则不会调用 LoadPostData() 方法。[编辑:在 Init() 期间调用 Page.RegisterRequiresPostback 克服了这个问题。] 我可以理解为什么,但它是相当有限的。
我通过在 LoadPostData() 方法期间根本不处理它来克服这个问题。相反,我在 OnLoad() 中调用的方法中处理了它。
使用这种方法时需要记住两件事:
1) 您不再有权访问作为参数传递给 LoadPostData() 方法的 postCollection NameValueCollection 对象。这意味着您必须从 Request.Form 集合中提取发布数据,这是一项稍微困难的工作。2) 由于 OnLoad() 发生在 ViewState 处理代码之后,因此您需要在创建 ListItems 后手动设置 SelectedValue。如果不这样做,如果列表框是通过 AJAX 填充的并且用户进行了选择,则该选择将会丢失。
我希望这对将来的人有帮助。
| 归档时间: |
|
| 查看次数: |
7090 次 |
| 最近记录: |