web-dev-qa-db-fra.com

Modifier la classe d'élément du répéteur li si elle est la première ou la dernière

J'utilise le répéteur pour créer une liste ul li dynamique

Est-il possible de contrôler la classe si l'élément est le premier ou le dernier?

Quelque chose comme:

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

en passant, qu'est-ce que cela signifie vraiment: <%# dans ASP.NET

Quelle est la différence entre <%# et <%=?

31
gruber

Il est assez facile de déterminer si l'élément est le premier ou non (Container.ItemIndex == 0), mais pour déterminer si l'élément est le dernier ou non, vous devez utiliser une propriété personnalisée qui sera initialisée à droite avec la liaison de données:

protected int ItemCount { get; set; }

Voici un exemple de répéteur:

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

voici un exemple de liaison de données:

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

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

et enfin une méthode d'aide:

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

Cela produira:

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

J'utilise généralement quelque chose comme ceci:

<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>
40
nelsestu

Si possible, je recommanderais d'utiliser quelque chose comme jQuery pour cela car cela rend l'implémentation de ce type de fonctionnalité très facile. Par exemple, vous pourriez avoir quelque chose comme ceci:

<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");
6
Mun

J'ai modifié la solution de nelsestu et j'ai trouvé:

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

Essayez quelque chose comme ça, si vous n'utilisez pas 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>
3
Bala R

Je n'ai pas pu utiliser la réponse d'Alex directement. Voici les modifications que j'ai apportées et qui ont fonctionné pour moi. En utilisant "l'exemple de répéteur" d'Alex pour la balise asp: Repeater, utilisez ceci dans le code derrière:

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";
}
1
Mark

Quant à votre question sur la différence entre <% = et <% #, veuillez consulter les liens suivants:

Blocs de rendu de code:

http://msdn.Microsoft.com/en-us/library/k6xeyd4z (v = vs.71) .aspx

Syntaxe d'expression de liaison de données:

http://msdn.Microsoft.com/en-us/library/bda9bbfx (v = vs.71) .aspx

1
camainc

Pour ceux qui en ont besoin en VB, voici ce qui fonctionne pour moi.

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

J'avais besoin d'un diviseur pour montrer tous les articles sauf le dernier.

0
CBarr

Je le fais généralement comme ça pour le dernier article

 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

et voici comment je l'utilise dans le balisage HTML

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

Si vous utilisez des contrôles dans votre ItemTemplate, vous pouvez faire quelque chose comme ceci, ajoutez l'événement 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);
}
0
victoryoalli