【问题标题】:Change repeater li item class if first or last如果第一个或最后一个更改中继器 li 项目类
【发布时间】:2017-02-16 01:52:42
【问题描述】:

我正在使用转发器来创建动态 ul li 列表

是否可以控制类是第一个还是最后一个?

类似:

class="<%# if(Container.ItemIndex == 0)
   {
        class = ... 
   }
   ) %>"

顺便说一句,它的真正含义是:&lt;%# 在 ASP.NET 中

&lt;%#&lt;%= 有什么区别?

【问题讨论】:

  • 您是在线执行此操作还是使用代码隐藏页面执行此操作?如果您从代码隐藏页面加载项目,则很容易引用索引 0 项目以及最后一个索引是什么。
  • 还有 FIRST/LAST 的 CSS 选择器可以使用,我认为它们对 IE8 的支持很差(就像一半的 CSS 一样)

标签: c# .net asp.net


【解决方案1】:

判断元素是否是第一个(Container.ItemIndex == 0)很容易,但要确定元素是否最后一个,您必须使用自定义属性,该属性将通过数据绑定正确初始化:

protected int ItemCount { get; set; }

这是一个转发器示例:

<asp:Repeater runat="server" ID="repeater">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li class="<%# GetItemClass(Container.ItemIndex) %>">
            <%# Container.DataItem %>
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>

这里是一个数据绑定的例子:

public override void DataBind()
{
    var data = new string[] { "first", "second", "third" };
    this.ItemCount = data.Length;

    repeater.DataSource = data;
    repeater.DataBind();
}

最后是一个辅助方法:

protected string GetItemClass(int itemIndex)
{
    if (itemIndex == 0)
        return "first";
    else if (itemIndex == this.ItemCount - 1)
        return "last";
    else
        return "other";
}

这将产生:

<ul>
    <li class="first">
        first
    </li>
    <li class="other">
        second
    </li>
    <li class="last">
        third
    </li>
</ul>

【讨论】:

  • 你也可以设置被绑定的数据类,有一个字段; 1)ClassString(不利于设计分离)2)IsFirst/IsLast标志(不能很好地扩展)3)索引
  • 我需要这个,但我不太明白如何使用它。您是否建议创建一个自定义转发器对象,该对象使用新属性和重写的 DataBind 方法扩展转发器?否则,由于您的 repeater.DataBind() 在 DataBind() 方法本身内,因此如何实际调用 DataBind() ?进一步说明:我能够通过一些修改使其工作。请参阅下面的答案...
  • @dadwithkids,不需要扩展repeater,因为DataBind方法定义在System.Web.UI.Control中,任何控件甚至页面都可以覆盖它。
  • 当然else if (itemIndex == this.ItemCount - 1) 不起作用...this 将是页面! (如果方法在页面上定义。)
  • @Alex:啊,我的错!我认为ItemCount 是中继器本身的属性!我现在看到您在页面上定义它,并手动更新它。道歉。
【解决方案2】:

我通常使用类似以下的内容:

<asp:Repeater ID="rptItems" runat="server" ViewStateMode="Disabled">
  <ItemTemplate>
    <li<%# Container.ItemIndex == ((IList)((Repeater)Container.Parent).DataSource).Count-1 ? " class='last'" : ""%>>
...
    </li>
  </ItemTemplate>
</asp:Repeater>

【讨论】:

  • 查克·诺里斯(Chuck Norris)的批准印章,您还想要什么 :) 谢谢,也帮助了我!
  • 这里是 VB.NET 版本:
  • 如果中继器的源是 DataTable,则这里是解决方案 "%>
【解决方案3】:

如果可能,我建议使用 jQuery 之类的东西,因为它可以很容易地实现这种类型的功能。例如,你可以有这样的东西:

<asp:Repeater id="MyRepeater" runat="server">
    <HeaderTemplate><table class="MyRepeater"></HeaderTemplate>
    <FooterTemplate></table></FooterTemplate>
    <ItemTemplate><tr><td>My Data</td></tr></ItemTemplate>
</asp:Repeater>

$("table.MyRepeater tr:last").attr("class", "last");

【讨论】:

  • 我也是这样处理的。
  • 请注意,如果您有多个样式相似的列表需要执行相同的操作,请使用 :last-child 而不是 :last
  • 你也可以用.addClass(...)代替.attr(...)来设置CSS-class。
【解决方案4】:

如果您不使用 jQuery,请尝试这样的事情

 <asp:Repeater ID="Repeater1" runat="server">
    <ItemTemplate>
        <asp:Label ID="Label1" CssClass='<%# Container.ItemIndex == 0 ? "first" : "notFirst" %>' runat="server" Text="Label"></asp:Label>
    </ItemTemplate>
    </asp:Repeater>

【讨论】:

  • 但它只处理如果我想添加第二个条件例如 if second 或 if last 怎么办?
【解决方案5】:

我修改了 nelsestu 的解决方案并想出了:

<%# Container.ItemIndex == ((System.Data.DataTable)((Repeater)Container.Parent).DataSource).Rows.Count-1 ? "</div>" : string.Empty %>

【讨论】:

    【解决方案6】:
    【解决方案7】:

    我无法直接使用 Alex 的答案。这是我所做的对我有用的修改。使用 Alex 的“中继器示例”作为 asp:Repeater 标签,在后面的代码中使用它:

    private string[] data = new string[] { "first", "second", "third" };
    protected int ItemCount { get; set; }
    
    private void Page_Load(object sender, EventArgs e)
    {
        // normally one would fetch the data here right before binding like this:
        // data = SomeService.SomeMethodToGetData();
        repeater.DataSource = data;
        repeater.DataBind();
    }
    
    public override void DataBind()
    {
        ItemCount = data.Count();
    }
    
    protected string GetItemClass(int itemIndex)
    {
        if (itemIndex == 0)
            return "first";
        else if (itemIndex == this.ItemCount - 1)
            return "last";
        else
            return "other";
    }
    

    【讨论】:

      【解决方案8】:

      我通常对最后一项是这样的

       Public m_recordCount As Integer
      Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
          ltrlTitle.Text = m_title
      
          Using Context As New MyEntities
              Dim m_lst = Context.getHotRecords(m_location).ToList
              m_recordCount = m_lst.count()
      
              rptListings.DataSource = m_lst
              rptListings.DataBind()
          End Using
      
      End Sub
      

      这是我在 HTML 标记中使用它的方式

       <div <%# IIf(m_recordCount - 1 = Container.ItemIndex, "class='clearBorder'", "")%>>
      

      【讨论】:

        【解决方案9】:

        对于那些在 VB 中需要此功能的人,这对我有用。

        <span runat="server" class='divider' 
            Visible="<%# Container.ItemIndex < DirectCast(DirectCast(Container.Parent,Repeater).DataSource,List(Of IList)).Count()-1 %>">|</span>
        

        我需要一个分隔线来显示除最后一项之外的所有项目。

        【讨论】:

          【解决方案10】:

          如果您在 ItemTemplate 中使用控件,则可以执行以下操作,添加 OnItemDataBound 事件。

          <asp:Repeater ID="RptId" runat="server" OnItemDataBound="OnItemDataBound">
            <ItemTemplate>
              <asp:Panel runat="server" ID="PnlCtrlItem">
                <%#Eval("Content") %>
              </asp:Panel>
            </ItemTemplate>
          </asp:Repeater>
          
          protected void OnItemDataBound(object sender, RepeaterItemEventArgs e)
          {
              if (e.Item.ItemIndex == 0)
                ((Panel) e.Item.FindControl("PnlCtrlItem")).CssClass = "first";
              //or the following to have your control indexed
              ((Panel) e.Item.FindControl("PnlCtrlItem")).CssClass = string.Format("item-{0}",e.Item.ItemIndex);
          }
          

          【讨论】:

            猜你喜欢
            • 2010-11-22
            • 1970-01-01
            • 1970-01-01
            • 2021-12-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多