2008-11-29 47 views
7

Tengo una página ASP.NET que usa un repetidor anidado dentro de otro repetidor para generar una lista de datos. Es el efecto de los siguientes:¿Cómo puedo ocultar un repetidor en ASP.NET C# si el DataSource no contiene elementos?

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

En el (C#) de código subyacente que estoy básicamente usando LINQ para tirar de una lista de información de un documento XML y se unen esa información para el primer repetidor.

Buscando la respuesta a esto, parece que el método es determinar si los datos para el repetidor anidado están vacíos. Si es así, entonces establece la visibilidad del repetidor en falso.

Desafortunadamente, no he podido determinar cómo hacerlo en línea, y no en el código subyacente (ya que no necesariamente funcionará para lo que estoy haciendo).

Como mis páginas no son validadas ahora, porque la UL termina vacía para cualquier elemento sin Data2, y porque me gustaría seguir usando una lista desordenada, busco su ayuda.

¿Alguna idea?

Gracias!

ACTUALIZACIÓN:

Si ayuda, ya que podría muy bien ser posible hacerlo en el código subyacente, el LINQ es algo a este efecto:

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(); 

Respuesta

10

esto no va a ocultar el repetidor por completo, pero se puede subclase el control Repeater para que incluya una plantilla de datos vacío GridView como:

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); 
     } 
    } 
} 

Puede ellas utilizarlo en su.aspx como este:

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

Al llegar a su consulta LINQ ejecutado, verifique su propiedad Count (proporcionando una lista de algún tipo). Si es 0, simplemente convierta la propiedad Visible en falso.

+0

que está en el código subyacente no ... "en línea", como él pidió. Estaba a punto de decir lo mismo, luego leí un poco más cerca :) –

+0

En caso de que sea posible, he agregado el LINQ a la pregunta original. –

0

Por lo que sé, debe hacerlo a través del código subyacente, simplemente use el evento ItemDataBound para manejarlo, puede dejar casi todo como está, simplemente ingrese alguna lógica que obtenga el conjunto de datos y determine si tiene entradas , si no esconder el repetidor.

3

Pruebe algo como:

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

para el repetidor anidada

0

no creo que lo que está haciendo va a trabajar consigo un error al intentar establecer el origen de datos y como eres Intentando hacer; sin embargo, en el código que está detrás de usted, haga esto:

Suponiendo que ha agregado un detector al ItemDataBoundEvent de su repetidora principal, necesitará cambiar ligeramente su consulta linq para no usar un tipo anónimo (Crear una clase protegida que tenga sus propiedades) En mi caso, estoy usando dto como nombre de clase.

void rep1_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 

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

Me encantaría saber por qué crees que no puedes resolver esto en el código.

2

¿Por qué no utilizar un ListView? Ofrece muchas de las mismas funciones, incluida una EmptyDataTemplate.

+0

Buena pregunta :) Creo que estaba apuntando a .NET Framework 2.0 en ese momento. –

0

Sé que este es un hilo viejo y la respuesta anterior es una solución muy buena, pero tuve un problema similar y encontré otra solución simple que pensé que también compartiría. Esto valida muy bien y muestra lo mismo.

acaba de cambiar su plantilla de pie de página:

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

O si el uso de tablas:

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

la esperanza de que ayude a alguien!

+0

Gracias por compartir. –

0

En el OnItemDataBound caso, la visibilidad se establece en false si ItemType es una Header y establecer la visibilidad a cierto si ItemType es un Item.

1

uso esto:

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

Una implementación más en PreRender (VB): Repetidor de intensidad reducida = CType (emisor, repetidor) repetidor.Visible = repetater.Items.Count> 0 – Brent

Cuestiones relacionadas