数据服务控件的嵌套最主要的是是内层控件数据的加载和事件的触发.下面以两层DataList为例介绍下实现的过程.效果如图:
注意
:内层控件数据绑定与事件声明在外层的ItemDataBind中实现;例子中外层DataList的Id为dlQuestion,内层为dlItem;代码如下
private
void
dlQuestion_ItemDataBound(
object
sender, System.Web.UI.WebControls.DataListItemEventArgs e)
... {
if ( e.Item.ItemType == ListItemType.EditItem || e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem )
...{
LinkButton lb = (LinkButton)e.Item.FindControl("lbtnDelete");
if ( lb != null )
lb.Attributes.Add("onclick", "return confirm('确实要删除么?')");
//得到内层DataList
DataList dlItem= (DataList)e.Item.FindControl("repItem");
if ( dlItem != null )
...{
if ( ViewState["repIndex"] != null )
...{
dlItem.EditItemIndex = (int ) ViewState["repIndex"];
}
dlItem .ItemCommand += new DataListCommandEventHandler(dlItem_ItemCommand);
dlItem .ItemDataBound += new DataListItemEventHandler(dlItem_ItemDataBound);
int qid = ((InvQuestion)e.Item.DataItem).Que_Id;
ArrayList al = InvController.GetItemCollection( qid );
dlItem .DataSource = al;
dlItem .DataBind();
}
}
}
... {
if ( e.Item.ItemType == ListItemType.EditItem || e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem )
...{
LinkButton lb = (LinkButton)e.Item.FindControl("lbtnDelete");
if ( lb != null )
lb.Attributes.Add("onclick", "return confirm('确实要删除么?')");
//得到内层DataList
DataList dlItem= (DataList)e.Item.FindControl("repItem");
if ( dlItem != null )
...{
if ( ViewState["repIndex"] != null )
...{
dlItem.EditItemIndex = (int ) ViewState["repIndex"];
}
dlItem .ItemCommand += new DataListCommandEventHandler(dlItem_ItemCommand);
dlItem .ItemDataBound += new DataListItemEventHandler(dlItem_ItemDataBound);
int qid = ((InvQuestion)e.Item.DataItem).Que_Id;
ArrayList al = InvController.GetItemCollection( qid );
dlItem .DataSource = al;
dlItem .DataBind();
}
}
}
其中ViewState对状态信息的读取和下面的保存联系后再讨论;
下面以内层DataList的Edit事件为例;
在内层DataList中e.CommandName="edit"事件中必须保存ViewState["index"] = e.Item.Index信息;否则在e.CommandName="update"中得不到editIndex的信息.需要保存ViewState的原因是:由于暂时没有找到更好的方法,内层DataList数据绑定需要在每个事件发生时对外层DataList重新绑定,也就是在Page.Load中加载DataBind()事件,对效率有一定影响
private
void
dlItem_ItemCommand(
object
source, DataListCommandEventArgs e)
... {
if ( e.CommandName == "edit")
...{
int qid = 0;
//得到外层datalist
DataList dllist = (DataList)e.Item.Parent.Parent.Parent;
//取得外层Question记录的Id
HtmlInputHidden lbEditNum = (HtmlInputHidden)dllist.Items[0].FindControl("hidQuestion");
if ( lbEditNum.Value != "")
...{
qid = int.Parse(lbEditNum.Value);
}
//得到内层DataList
DataList dl = (DataList)e.Item.Parent;
dl.EditItemIndex = e.Item.ItemIndex;
//保存状态信息
ViewState["repIndex"] = e.Item.ItemIndex;
// Response.Write(e.Item.ItemIndex);
//重新绑定内层DataList数据
ArrayList al = InvController.GetItemCollection( qid );
dl.DataSource = al;
dl.DataBind();
}
}
... {
if ( e.CommandName == "edit")
...{
int qid = 0;
//得到外层datalist
DataList dllist = (DataList)e.Item.Parent.Parent.Parent;
//取得外层Question记录的Id
HtmlInputHidden lbEditNum = (HtmlInputHidden)dllist.Items[0].FindControl("hidQuestion");
if ( lbEditNum.Value != "")
...{
qid = int.Parse(lbEditNum.Value);
}
//得到内层DataList
DataList dl = (DataList)e.Item.Parent;
dl.EditItemIndex = e.Item.ItemIndex;
//保存状态信息
ViewState["repIndex"] = e.Item.ItemIndex;
// Response.Write(e.Item.ItemIndex);
//重新绑定内层DataList数据
ArrayList al = InvController.GetItemCollection( qid );
dl.DataSource = al;
dl.DataBind();
}
}