Repeater控件中使用if语句的完美解决方案

来源:互联网 发布:linux文件夹同步软件 编辑:程序博客网 时间:2024/06/06 13:22

Repeater控件中使用if语句的完美解决方案

原文: 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 onmouseover="this.stop()" onmouseout="this.start()">