原文: http://hi.baidu.com/robert080610/blog/item/c547a8029ba688e008fa93aa.html
想用<marquee>嵌套repeater制作,这一点没问题,可是在设置repeater模板时出了问题,判断数据库中的一条记录strIMG字段的值是否为空,若为空则显示文字链接,不为空则显示图片链接,代码如下:
<marquee behavior=scrool>
<asp:repeater id="rptLinks" runat=server>
<HeaderTemlate>
<table>
<HeaderTemlate>
<FooterTemlate>
</table>
<FooterTemlate>
<ItemTemlate>
<%if (Eval("strIMG")!=null){%>
<tr><td><li><a href='<%#Eval("strURL")%>'><img src='<%#Eval("strIMG")%>' /></a></li></td></tr>
<%}else{%>
<tr><td><li><a href='<%#Eval("strURL")%>'><%#Eval("strName")%></a></li></td></tr>
<%}%>
<ItemTemlate>
</asp:repeater>
</marquee>
运行时提示Eval()只能在数据绑定是使用之类的警告,于是就去到网上查,已开始认为是我用错了,于是把以上代码改成:
<marquee behavior=scrool>
<asp:repeater id="rptLinks" runat=server>
<HeaderTemlate>
<table>
<HeaderTemlate>
<FooterTemlate>
</table>
<FooterTemlate>
<ItemTemlate>
<%if (DataBinder.Eval(Container.DataItem,"strIMG")!=null){%>
<tr><td><li><a href='<%#Eval("strURL")%>'><img src='<%#Eval("strIMG")%>' /></a></li></td></tr>
<%}else{%>
<tr><td><li><a href='<%#Eval("strURL")%>'><%#Eval("strName")%></a></li></td></tr>
<%}%>
<ItemTemlate>
</asp:repeater>
</marquee>
结果提示Container对象未被实例化就使用云云,最后知道这种用法是.NET1.1的用法.NET2.0已经用Eval("XXX")代替了DataBinder.Eval(DataItem,"XXX")
只好再去查,最后终于找到一种解决方法:
<marquee behavior=scrool>
<asp:repeater id="rptLinks" runat=server>
<HeaderTemlate>
<table>
<HeaderTemlate>
<FooterTemlate>
</table>
<FooterTemlate>
<ItemTemlate>
<%if((((DataView)rptLinks.DataSource).Table.Rows[_nIndex++]["strIMG"])!=null) { %>
<tr><td><li><a href='<%#Eval("strURL")%>'><img src='<%#Eval("strIMG")%>' /></a></li></td></tr>
<%}else{%>
<tr><td><li><a href='<%#Eval("strURL")%>'><%#Eval("strName")%></a></li></td></tr>
<%}%>
<ItemTemlate>
</asp:repeater>
</marquee>
这种方法我没有测试,原因引用原作者的话是:“这个方法在进行复杂判断绑定数据时确实有效,但是我并不推荐这样的做法!因为这样的做法并不符合面向对象的封装特性,或者说,它是以破坏了封装特性的做法使之透明,来完成判断功能的。 我推荐的做法是,使用“自定义用户控件”来完成复杂的判定绑定任务。 ”这段代码应该是没问题,但我还是决心找一种更完美的方法去实现。
原作者说用自定义控件,我试了一下,结果还免不了去破坏封装性,只是对外不表现出来而已,可以认为这种方法是在破坏了封装性的基础上重新封装,所以也不好。
最后受有些人用DataBinding事件去做一些事启发,想到用ItemCreateed事件去完成,这也应该是最完美的方法了,呵呵,现在分享出来,最终代码如下:
<marquee behavior=scrool>
<asp:repeater id="rptLinks" OnItemCreateed="rptLinks_ItemCreateed" runat=server>
<HeaderTemlate>
<table>
<HeaderTemlate>
<FooterTemlate>
</table>
<FooterTemlate>
<ItemTemlate>
<tr id="rowIMGLink" runat=server ><td><li><a href='<%#Eval("strURL")%>'><img src='<%#Eval("strIMG")%>' /></a></li></td></tr> //不过原文这是少了runat=server
<tr id="rowWordLink" runat=server ><td><li><a href='<%#Eval("strURL")%>'><%#Eval("strName")%></a></li></td></tr>
<ItemTemlate>
</asp:repeater>
</marquee>
一下是新添加的窗体事件rptLink_ItemCreated:
protected void rptLink_ItemCreated(object sender, RepeaterItemEventArgs e)
{
if (e.Item.DataItem != null)
{
if (((DataRowView)e.Item.DataItem).Row["strIMG"] == null || ((DataRowView)e.Item.DataItem).Row["strIMG"].ToString() == "")
{
e.Item.FindControl("rowIMGLink").Visible = false;
e.Item.FindControl("rowWordLink").Visible = true;
}
else
{
e.Item.FindControl("rowIMGLink").Visible = true;
e.Item.FindControl("rowWordLink").Visible = false;
}
}
}
至此问题解决,但还有一个问题是,用以上代码产生的滚动链接会一直不停的滚动,这个在点击的时候很不方便,所以最后我又为<marquee>加了鼠标悬停代码:
<marquee behavior=scrool οnmοuseοver="this.stop()" οnmοuseοut="this.start()">