2004-6-7+ 有条件的对DataList中的特定控件进行操作
DataList是用摸板来重复显示内容的容器控件,除了在前台定好要显示的内容之外,还可以在后台操作控件。
先来看这样一个问题:看本站的留言本,这个留言本只有一个页面。在管理员没有登陆的时候,你看不到管理功能的选项,而当你登陆后,就可以使用管理功能。其实是通过下面的语句来实现的:
<%if session("login")="ok" then%>
delete reply
<%end if%>
而现在我们用DataList来做留言板,这些东西就不能放到前台了(因为违反asp.net的编程原则),但其实也没有必要放前面,因为DataList提供了实现这种有条件的操作DataList的特定控件的办法,那就是使用ItemCreated或者ItemDataBound。
ItemCreated
当创建 DataList 控件中的项时(不论是在往返行程中还是在将数据绑定到控件时),都会引发 ItemCreated 事件。ItemCreated 事件通常用于控制 DataList 控件中行的内容和外观。
ItemDataBound
当项被数据绑定到 DataList 控件后,将引发 ItemDataBound 事件。此事件为您提供了在客户端显示数据项之前访问该数据项的最后机会。当引发此事件后,该数据项将被设为空,并且不再可用。
上面是sdk文档里对于这两个事件的解释,用我的话解释一下就是:当DataList被创建前,你可以有机会修改在DataList里面的控件的属性,比如你在DataList的ItemTemplate里放了一个用于回复的按钮,设定为只有Session["login"]=="ok"才可以显示,这样就可以在ItemDataBound事件里添加一个判断,具体实现看下面:
private void listitem_bound(object sender,DataListItemEventArgs e)
{
//根据模板类型来进行具体的操作,这个地方很重要的。在文章的最后会讨论这个问题,我在处理这个部分的时候发现了一个有趣的现象
if((e.Item.ItemType==ListItemType.Item)||(e.Item.ItemType==ListItemType.AlternatingItem))
{
//找到要进行特别设置的控件,注意这个地方影响的是所有这个id的控件,而不是说只是单独某一行的某一个控件
LinkButton butreplys=(LinkButton)e.Item.FindControl("butreply");
//具体的判断操作
if(Session["login"]=="ok")
{
butreplys.Visible=false;
}
else
{
butreplys.Visible=true;
}
}
}
这样就完成了对这个按钮的保护,剩下的,只是在DataList中指定响应事件的方法,还要注意给你的Session起一个不容易被猜到的名字。
<asp:DataList ID="listbound" runat="server" OnItemDataBound="listitem_bound">
<itemtemplate>
<asp:LinkButton ID="butreply" runat="server" Text="reply"></asp:LinkButton>
<asp:Label ID="labmsg" runat="server" Text="sd"></asp:Label>
</itemtemplate>
<headertemplate>测试</headertemplate>
</asp:DataList>
或许还要问ItemDataBound和ItemCreated的区别,在我看来,他们的区别仅在于发生时间上的差异,并且后发生的ItemDataBound事件中的操作会覆盖掉在它之前发生的ItemCreated事件中的对同一个控件的操作。
最后我们来看一下这个语句:
if((e.Item.ItemType==ListItemType.Item)||(e.Item.ItemType==ListItemType.AlternatingItem))
这个是用来判断模板类型的,如果你的DataList中只有ItemTemplate,那就没有必要用这一步,但是如果DataList里还有别的模板,比如HeaderTemplate等,那就需要用这个语句来指明是从哪个模板里面找这个控件。而且有意思的是,如果你在DataList中没有定义AlternatingItemTemplate而只是有ItemTemplate,并且在方法中只是判断了e.Item.ItemType==ListItemType.Item而没有用后面那快,那对控件的操作就是隔行的,也就是说,如果没有定义AlternatingItemTemplate,那DataList就自己隐蔽的使用了这个模板,并且没有告诉你。但是如果只判断后面而没有前面,那你将一无所获。(上面的这个原因是我猜的,不过大致应该就是如此)。
有关ItemType和ListItemType的更详细的信息,可以参看SDK文档。