2008-11-29 8 views
7

Mam stronę ASP.NET, która używa repeatera zagnieżdżonego w innym repeater w celu wygenerowania listy danych. To w ten sposób z następujących powodów:Jak ukryć repeater w ASP.NET C#, jeśli DataSource nie zawiera żadnych elementów?

<asp:Repeater> 
    <ItemTemplate> 
     <span><%#Eval("Data1") %></span> 
     <!-- and many more --> 
     <asp:Repeater DataSource='<%#Eval("Data2")%>'> 
      <HeaderTemplate> 
       <ul> 
      </HeaderTemplate> 
      <ItemTemplate> 
       <li><%#Container.DataItem%></li> 
      </ItemTemplate> 
      <FooterTemplate> 
       </ul> 
      </FooterTemplate> 
     </asp:Repeater> 
    </ItemTemplate> 
</asp:Repeater> 

W (C#) kodu źródłowego Ja w zasadzie za pomocą LINQ ciągnąć listę informacji z dokumentu XML i powiązać te informacje do pierwszego repeater.

Szukając odpowiedzi na to pytanie, wydaje się, że metodą jest ustalenie, czy dane dla zagnieżdżonego przemiennika są puste. Jeśli tak, ustaw widoczność wzmacniacza na wartość false.

Niestety, nie byłem w stanie określić, jak to zrobić, a nie w kodzie źródłowym (ponieważ niekoniecznie będzie to działało dla tego, co robię).

Ponieważ moje strony nie sprawdzają teraz, ponieważ ul kończy się być pusty dla jakichkolwiek elementów bez Data2, a ponieważ chciałbym nadal używać nieuporządkowanej listy, szukam twojej pomocy.

Wszelkie pomysły?

Dzięki!

UPDATE:

Jeśli to nie pomaga, ponieważ może to równie dobrze być możliwe do wykonania w kodzie-tyłu, LINQ jest coś w tej sprawie:

var x = from y in z 
    select new { 
     Data1 = d, 
     // etcetera 
     Data2 = (from j in k 
      where j.Value != String.Empty 
      select j.Value).ToList() 
    }; 

blah.DataSource = x; 
blah.DataBind(); 

Odpowiedz

10

To nie ukryj repeater całkowicie, ale można podklasy kontroli Repeater tak, że zawiera GridView-jak pusty szablon danych:

using System; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

public class EmptyCapableRepeater : Repeater 
{ 
    public ITemplate EmptyDataTemplate { get; set; } 

    protected override void OnDataBinding (EventArgs e) 
    { 
     base.OnDataBinding(e); 

     if (this.Items.Count == 0) 
     { 
      EmptyDataTemplate.InstantiateIn(this); 
     } 
    } 
} 

Można ich używać w.aspx jak to:

<custom:EmptyCapableRepeater runat="server" ID="rptSearchResults"> 
    <ItemTemplate> 
     <%# Eval("Result")%> 
    </ItemTemplate> 
    <SeparatorTemplate> 
     <br /> 
    </SeparatorTemplate> 
    <EmptyDataTemplate> 
     <em>No results were found.</em> 
    </EmptyDataTemplate> 
</custom:EmptyCapableRepeater> 
0

Gdy pojawi się zapytanie LINQ wykonane, sprawdź jego właściwość Count (podając jej listę). Jeśli jest 0, to po prostu ustaw właściwość Visible na false.

+0

To w opóźnieniem kodu ... Nie „inline” jak poprosił. Już miałem powiedzieć to samo, a potem czytałem trochę bliżej :) –

+0

Jeśli jest to możliwe, dodałem LINQ do pierwotnego pytania. –

0

Z tego co wiem, musisz to zrobić poprzez funkcję codebehind, po prostu użyj zdarzenia ItemDataBound, aby go obsłużyć, możesz zostawić prawie wszystko tak, jak jest, po prostu wprowadź logikę, która pobiera zestaw danych i określa, czy ma wpisy , jeśli nie, ukryj przekaźnik.

3

Spróbuj czegoś takiego:

<asp:Repeater runat="server" DataSource='<%#Eval("Data2")%>' 
    Visible='<%# ((IEnumerable)Eval("Data2")).GetEnumerator().MoveNext() %>'> 

dla zagnieżdżonego repeater

0

Nie sądzę, co robisz będzie działać pojawia się błąd, gdy próbuję i ustawić DataSource jak ty próbować zrobić; jednak w kodzie za Tobą wykonaj to:

Zakładając, że dodałeś słuchacza do ItemDataBoundEvent nadajnika macierzystego, musisz nieco zmienić zapytanie linq, aby nie używać typu anonimowego (Utwórz klasę chronioną, która ma twoje właściwości) W przypadku mjy używam dto jako nazwy klasy.

void rep1_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 

    Repeater rep2 = (Repeater)e.Item.FindControl("rep2"); 
    rep2.DataSource = ((dto)e.Item.DataItem).y; 
    rep2.DataBind(); 
} 

Chciałbym się dowiedzieć, dlaczego uważasz, że nie możesz rozwiązać tego problemu w kodzie.

2

Dlaczego nie korzystać z ListView? Oferuje wiele takich samych funkcji, w tym EmptyDataTemplate.

+0

Dobre pytanie :) Wydaje mi się, że w tym czasie byłem kierowany na .NET Framework 2.0. –

0

Wiem, że jest to stary wątek, a powyższa odpowiedź jest bardzo dobrym rozwiązaniem, ale miałem podobny problem i znalazłem inne, różniące się proste rozwiązanie, które myślałem, że również bym się podzielił. To potwierdza dokładnie i wyświetla to samo.

Wystarczy zmienić szablon stopki do:

<FooterTemplate> 
      <li style="display:none;">This will not show.</li></ul> 
</FooterTemplate> 

lub jeśli przy użyciu tabel:

<FooterTemplate> 
      <tr> style="display:none;"><td>But something must be in here.</td></tr></table> 
</FooterTemplate> 

nadzieję, że pomoże ktoś!

+0

Dzięki za udostępnienie. –

0

W OnItemDataBound zdarzeń, ustawić widoczność na false jeśli ItemType jest widoczność true Header i ustawić jeśli ItemType jest Item.

1

użyj:

protected void Repeater1_PreRender(object sender, EventArgs e) 
{ 
    if (Repeater1.Items.Count < 1) 
    { 
     container.Visible = false; 
    } 
} 
+0

Więcej implementacji w PreRender (VB): Dim repeater = CType (nadajnik, repeater) repeater.Visible = repeater.Items.Count> 0 – Brent

Powiązane problemy