我有一个动态加载的控件,它包含一个中继器和其他项目,如一组文本框。
该控件用于地址验证。
过程是:
- 控制显示
- 用户输入地址信息
- 页面返回,控件根据web服务验证地址信息
- 如果地址不是100%,则会显示潜在匹配项的列表<-这种情况发生在中继器中。换句话说,它在代码中是数据绑定的
- 用户选中要接受的复选框旁边的复选框
- 页面向后发布
到目前为止,有1-6个工作。问题是,当页面返回时,没有中继器项目。
如何让中继器加载它的项目而不必运行另一个databind()操作?
如果不能做到这一点,我该如何有效地运行databind()?换句话说,在oninit期间,我没有控制street/city/state/zip值。那么,如何重新应用视图状态更改?
大多数控件都呈现为类似<input type="text" name="myId" id="myId/>
的HTML表单元素。
Web表单的一部分实际上只是所有这些的包装。
每当你需要获取原始值时,你只需在Request.Forms集合中查找与你要查找的控件的名称(通常由asp.net为控件的唯一性生成的唯一id和你的名称组成)一起发布的任何控件值。
这正是您所做的——您浏览了Forms集合,查看了发布到服务器的原始表单值。这也是您在创建自己的控件时实现IPostBackDataHandler接口时经常做的事情——您从Request.Forms.中提取值
复选框的烦人之处在于,对于"标准"HTML,只有勾选了复选框,它们才会被提交。
两个重要事实:
- 中继器项中的控件应在OnItemCreated和中创建,而不是在OnItemDataBound中创建
- OnItemCreated在Postback期间运行,而不必调用DataBind()
我一直在将用户控件加载到中继器项目中,用户控件的类型基于绑定到中继器的数据项目。因此,我将用户控件的类型添加到中继器项的视图状态中,以便在回发时运行的OnItemCreated(由于尚未调用DataBind(),因此没有要绑定的数据项)期间,它知道要加载什么类型的用户控件。然后将应用视图状态。
protected void rpTransactions_OnItemCreated(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var dataItem = e.Item.DataItem;
string typeName;
string viewStateKey = string.Concat("typeName", e.Item.ItemIndex);
if (dataItem == null)
{
typeName = ViewState[viewStateKey].ToString();
}
else
{
typeName = dataItem.GetType().ToString();
ViewState[viewStateKey] = typeName;
}
Control template = TransactionTemplateFactory(typeName);
template.ID = "trans";
e.Item.FindControl("phTransSpecific").Controls.Add(template);
}
}
如果OnItemDataBound中的代码运行,它会捕获这个用户控件并将其数据绑定到它