2013-06-18 15 views
9

Ich verwende ein ASP.NET Repeater, um den Inhalt eines <table> anzuzeigen. Es sieht etwa so aus:Wenn Anweisung in Repeater ItemTemplate

<table cellpadding="0" cellspacing="0"> 
    <asp:Repeater ID="checkboxList" runat="server" OnItemDataBound="OnCheckboxListItemBound"> 
     <ItemTemplate> 
      <tr id="itemRow" runat="server"> 
       <td> 
        Some data 
       </td> 
      </tr> 
     </ItemTemplate> 
    </asp:Repeater> 
</table> 

Es funktioniert gut, aber ich möchte in der ItemTemplate eine if() Aussage haben, so kann ich bedingt bestimmen, ob ich ein <tr> Tag drucken möchten aus.

So möchte Ich mag so etwas haben:

<table cellpadding="0" cellspacing="0"> 
    <asp:Repeater ID="checkboxList" runat="server" OnItemDataBound="OnCheckboxListItemBound"> 
     <ItemTemplate> 

      <% if ((CurrentItemCount % 2) == 0) { %?> 
      <tr id="itemRow" runat="server"> 
      <% } %> 
       <td> 
        Some data 
       </td> 
      <% if ((CurrentItemCount % 2) == 0) { %?> 
      </tr> 
      <% } %> 
     </ItemTemplate> 
    </asp:Repeater> 
</table> 

Gibt es irgendeine Weise, die ich dies erreichen können?

PS. Die CurrentItemCount ist nur erfunden. Ich brauche auch einen Weg, um die aktuelle Anzahl der Artikel innerhalb dieser if() Aussage zu bekommen. Aber ich scheine nur in der Lage zu sein, es von <%# Container.ItemIndex; %> zu bekommen, das mit einer if() Aussage nicht benutzt werden kann?

+0

Gibt es einen Grund, warum Sie nicht eine Gridview verwenden können tabellarische Daten angezeigt werden? –

+0

@Bartdude Ja, ich justiere bestehenden Code und ich möchte wirklich nicht viel Funktionalität umschreiben. Also, wenn es irgendwie mit meinem Code möglich ist, würde ich wirklich gerne dabei bleiben. – Vivendi

Antwort

1

würde ich Code-Behind verwenden:

protected void OnCheckboxListItemBound(Object sender, RepeaterItemEventArgs e) 
{ 
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
    { 
     HtmlTableRow itemRow = (HtmlTableRow) e.Item.FindControl("itemRow"); 
     itemRow.Visible = e.Item.ItemIndex % 2 == 0; 
    } 
} 
+0

Da ich das ID-Attribut der Zeile behalten musste, war dies die beste Lösung für mich. – Vivendi

+6

Diese Antwort zeigt nicht, wie eine if-Anweisung in einem ItemTemplate verwendet wird. Es sollte wirklich nur ein Kommentar sein. –

+0

@edward: aber es zeigt den besten Weg, wenn Sie eine if-Anweisung verwenden möchten und Sie eine Artikelvorlage verwenden. Best in Bezug auf Ausfallsicherheit im Allgemeinen und kompilieren Sie Zeitsicherheit. Es ist auch der besser lesbare und wartbare Weg. Eigentlich hat sogar OP dies bevorzugt. Ich würde ASP.NET verwenden, wenn ich noch klassisches ASP oder PHP kodieren möchte. Abgesehen davon kann ich das alles nicht in einen Kommentar schreiben. –

16

Wenn Sie versuchen, yo eine 2 Spalt Tabelle macht dies den Trick tun könnte

<%# Container.ItemIndex % 2 == 0 ? "<tr class='itemRow'>" : "" %> 
    <td> 
     Some data 
    </td> 
<%# Container.ItemIndex % 2 != 0 ? "</tr> : "" %> 

ein paar Dinge geändert: id="itemRow" für alle Zeilen würde Wiederholte IDs verursachen, was nicht erlaubt ist.

Entfernt runat="server" da macht in diesem Zusammenhang keinen Sinn.

1

Ich habe 2 Beispiele für die Beispiele, die ich den Repeater auf ein Array von Strings (nur zu Demonstrationszwecken) binden

void BindCheckboxList() 
{ 
checkboxList.DataSource = new string[] { "RowA", "RowB", "RowC", "RowD", "RowE", "RowF", "RowG" }; 
checkboxList.DataBind(); 
} 

Beispiel 1: Eine Methode in de Code-Behind Erstellen Sie die gebundenen Elemente zurück en Casting bewerten was auch immer Wert Sie möchten.

erstellen Methode in Codebehind (Beispiel 1):

protected string StringDataEndsWith(object dataElement, string endsWith, string returnValue) 
{ 
// for now an object of the type string, can be anything. 
string elem = dataElement as string; 
    if (elem.EndsWith(endsWith)) 
    { 
    return returnValue; 
    } 
    else 
    { 
    return ""; 
    } 
} 

In der ASPX-Datei (Beispiel 1):

<asp:Repeater ID="checkboxList" runat="server"> 
<HeaderTemplate> 
    <table style="padding:0px;margin:0px;"> 
</HeaderTemplate> 
<ItemTemplate> 
    <%# StringDataEndsWith(Container.DataItem,"A","<tr id=\"itemRow\" runat=\"server\">") %> 
    <td> 
     <%# Container.DataItem %> 
    </td> 
    <%# StringDataEndsWith(Container.DataItem,"G","</tr>") %> 
</ItemTemplate> 
<FooterTemplate> 
    </table> 
</FooterTemplate> 
</asp:Repeater> 

Beispiel 2: Sie könnten eine direkte Besetzung in der ASPX verwenden Datei

Direct Beispiel (kein Code hinter):

<asp:Repeater ID="checkboxList" runat="server"> 
<HeaderTemplate> 
    <table style="padding:0px;margin:0px;"> 
</HeaderTemplate> 
<ItemTemplate> 
    <%# Convert.ToString(Container.DataItem).EndsWith("A") ? "<tr id=\"itemRow\" runat=\"server\">" : "" %> 
    <td> 
     <%# Container.DataItem %> 
    </td> 
    <%# Convert.ToString(Container.DataItem).EndsWith("G") ? "</tr>" : "" %> 
</ItemTemplate> 
<FooterTemplate> 
    </table> 
</FooterTemplate> 
</asp:Repeater> 

Ich hoffe, das ist, was Sie suchen. Grüße.

13

Ein anderer Weg, dies zu tun (wenn die Leistung ist kein Problem):

<ItemTemplate> 
    <!-- "If" --> 
    <asp:PlaceHolder runat="server" Visible="<%# MyCondition %>"> 
    <tr><td></td></tr> 
    </asp:PlaceHolder> 
    <!-- "Else" --> 
    <asp:PlaceHolder runat="server" Visible="<%# !MyCondition %>"> 
    <tr><td></td></tr> 
    </asp:PlaceHolder> 
</ItemTemplate> 
+0

Wie wirkt sich das auf die Leistung aus? –

+0

Nun, sehr abhängig von Ihrem Szenario natürlich. Meine Erfahrung ist, dass Sie in einem normalen Anwendungsfall die gleichen Anweisungen in allen Platzhaltern mehrmals ausführen, einen für jede Bedingung. Die Anweisungen innerhalb des ausgeblendeten Platzhalters werden weiterhin ausgeführt, obwohl kein Markup an den Client gesendet wird. – maets

+0

Wenn wir Visible auf false setzen, wird das Markup nicht an den Client gesendet. –

-1

Diese ganze Seite zeigt, wie schrecklich ASP Elementvorlage sind - schauen Sie sich die Optionen, die wir zur Auswahl ..

Also ich empfehle, Repeater komplett zu dumpen und normale Schleifen zu verwenden. Auf diese Weise haben Sie die volle Kontrolle über die Inhaltsausgabe & Logikfunktionen.

-Code hinter:

public void LoadMyData(object sender,EventArgs e) { 
    // ... your database stuff ... \\ 
    using (SqlDataReader reader=cmd.ExecuteReader()) { 
     ((DataTable)ServerSideDataObject_FromDatabase.DataSource).Load(reader); 
    } 
} 

aspx Code:

<div id="container"> 
    <asp:Repeater ID="ServerSideDataObject_FromDatabase" runat="server" OnLoad="LoadMyData"></asp:Repeater> <% // here for designer.cs, so it exists. Not used cause it's useless. %> 

    <% foreach (DataRow row in ((DataTable)ServerSideDataObject_FromDatabase.DataSource).Rows) { %> 
     <% String holycrap_icanhazvariablez = DateTime.Parse(row["the_date"].ToString()); %> 
     <h5> 
      <i class="fa fa-arrow-right" style="color:green;"></i> 
      <b><%= holycrap_icanhazvariablez %></b> 
      <% if (!String.IsNullOrEmpty(holycrap_icanhazvariablez)) {%> 
       : &nbsp; 
      <% } %> 
      <%= row["a_Description"] %> 
     </h5> 
     <div> 
      <%= RunMyFunction(int.Parse(row["ID"].ToString()))%> 
     </div> 

    <% } %> 
</div> 
+0

Oder verwenden Sie benutzerdefinierte Steuerelemente. Ich habe das angefangen, um das sauber zu halten. Es ist das gleiche wie oben, nur aufgeteilt in ein erweitertes webControl. – Barry