2011-03-11 35 views
41

El uso de VS 2008, tengo un control Repeater:Texto predeterminado para el control Repeater vacío

<asp:Repeater runat="server" ID="storesRep" DataSourceID="storeSqlDataSource" 
    OnItemDataBound="StoresRep_ItemDataBound"> 
    <ItemTemplate> 
     <table style="padding:0px"> 
     <tr> 
      <td style="width:200px"><asp:Label ID="infoLbl" runat="server"> 
       Choose stores for upload:</asp:Label>&nbsp;&nbsp;&nbsp;&nbsp; 
      </td> 
      <td style="width:110px"> 
       <asp:Label ID="storeLbl" runat="server" Text='<%# Bind("Name") %>'> 
       </asp:Label>&nbsp;&nbsp; 
      </td> 
      <td><asp:CheckBox runat="server" ID="storeCheck" /></td> 
     </tr> 
     </table> 
    </ItemTemplate> 
</asp:Repeater> 
<asp:SqlDataSource ID="storeSqlDataSource" runat="server" 
    ConnectionString="<%$ ConnectionStrings:someConnectionString %>" 
    SelectCommand="SELECT [StoreId], [Name] FROM [Store] Order By [Name]"> 
</asp:SqlDataSource> 

Ahora me gustaría mostrar un texto predeterminado como "No hay tiendas encontraron" si la fuente de datos no devolvió artículos de la base de datos. Hasta ahora, he utilizado principalmente GridView donde no tuve problemas debido al atributo EmptyDataText.

Respuesta

26

Se podría solucionar el hecho de que Repeater no es compatible con una forma intrínseca para llevar a cabo lo que está haciendo mediante el uso de la FooterTemplate en conjunción con el evento OnItemDataBound y que muestra el pie de página sólo cuando la fuente de datos devuelve ningún elemento.

ejemplos de cómo se puede hacer esto se pueden encontrar en:

Handling Empty Data in an ASP.NET Repeater control

How to show Empty Template in ASP.NET Repeater control?

+0

@marquito Si se siente triste por la disonancia semántica, siempre puede usar un 'Panel' y mostrar/ocultar eso en' OnItemDataBound' en lugar de FooterTemplate ... – pseudocoder

+0

@pseudocoder la tristeza proviene de la falta de un out de la caja para hacerlo. Además, me veo obligado a verificar cada elemento de datos solo para verificar si el resultado final está vacío. También debería haber un evento "OnFinishedDataBinding" que evitaría llamadas innecesarias a OnItemDataBound. – marquito

+0

Pude utilizar este enfoque con éxito después de varios intentos con diferentes métodos. Creo que usar 'panel' en lugar de' label' agregaría aún más flexibilidad, y espero probar eso también. ¡Gracias por compartir esto! –

62

Joaos respuesta incluso se puede simplificar. En el pie de página, no establezca lo visible-propiedad de su elemento por defecto false, pero el uso de la siguiente expresión:

<FooterTemplate> 
    <asp:Label ID="defaultItem" runat="server" 
     Visible='<%# YourRepeater.Items.Count == 0 %>' Text="No items found" /> 
</FooterTemplate> 

De esta manera, puede guardar el código subyacente.

+0

¿Qué elemento aplica la propiedad 'Visible'? –

-1

Si no desea jugar con su HTML con elementos ocultos (que realmente no les gusta las cosas que ocultan con JS):

Es probable que ya tienen una clase estática Utilidades que tiene propiedades estáticas en ella. (De lo contrario, haga clic en la solución y agregue -> clase)

Establecer pública static String hidden = ""; // en la nueva clase Utilidades creado

En su código detrás de archivo .cs hacer esto:

DataTable coll = .... 
if(coll.Rows.Count < 1) 
    Utils.hidden = "<span>Sorry, there were no items</span> 

A continuación, en el archivo .ascx la <FooterTemplate> se parece a esto:

<FooterTemplate> 
    <%# Utils.hidden %> 
</FooterTemplate> 
5

Incluso mejor : esta subclase agrega una propiedad EmptyDataTemplate. En su marcado, coloque un elemento tal como lo haría con un elemento. De forma predeterminada, esto ocultará el encabezado y el pie de página si no hay datos; puede cambiar esto con las propiedades HeaderVisibleWhenEmpty y FooterVisibleWhenEmpty en el marcado.

public class RepeaterWithEmptyDataTemplate : Repeater 
{ 
    public virtual ITemplate EmptyDataTemplate { get; set; } 

    protected virtual bool DefaultHeaderVisibleWhenEmpty 
    { 
     get { return false; } 
    } 

    protected virtual bool DefaultFooterVisibleWhenEmpty 
    { 
     get { return false; } 
    } 

    public bool HeaderVisibleWhenEmpty 
    { 
     get { return ViewState["hve"] == null ? DefaultHeaderVisibleWhenEmpty : (bool) ViewState["hve"]; } 
     set { ViewState["hve"] = value; } 
    } 

    public bool FooterVisibleWhenEmpty 
    { 
     get { return ViewState["fve"] == null ? DefaultFooterVisibleWhenEmpty : (bool) ViewState["fve"]; } 
     set { ViewState["fve"] = value; } 
    } 

    protected override void OnDataBinding(EventArgs e) 
    { 
     base.OnDataBinding(e); 
     if (Items.Count == 0 && EmptyDataTemplate != null) 
     { 
      var emptyPlaceHolder = new PlaceHolder {ID = "empty", Visible = true}; 
      EmptyDataTemplate.InstantiateIn(emptyPlaceHolder); 

      //figure out where to put placeholder 
      RepeaterItem footer = 
       Controls.OfType<RepeaterItem>().FirstOrDefault(i => i.ItemType == ListItemType.Footer); 
      if (footer == null) 
      { 
       //add to end if no footer 
       Controls.Add(emptyPlaceHolder); 
      } 
      else 
      { 
       Controls.AddAt(Controls.IndexOf(footer), emptyPlaceHolder); 
      } 

      //hide header and footer according to properties. 
      foreach (RepeaterItem x in Controls.OfType<RepeaterItem>()) 
      { 
       switch (x.ItemType) 
       { 
        case ListItemType.Header: 
         x.Visible = HeaderVisibleWhenEmpty; 
         break; 
        case ListItemType.Footer: 
         x.Visible = FooterVisibleWhenEmpty; 
         break; 
       } 
      } 
     } 
    } 
} 

la muestra en el marcado:

<myprefix:RepeaterWithEmptyDataTemplate runat=server> 
    <ItemTemplate>blah blah blah</ItemTemplate> 
    <EmptyDataTemplate>Hey, no data!</EmptyDataTemplate> 
</myprefix:RepeaterWithEmptyDataTemplate> 

Tenga en cuenta que el método DataBind se debe llamar, o no se mostrará el EmptyDataTemplate.

0

Sobre la base de la respuesta n. 3 I adoptó la siguiente solución que parece lo suficientemente bueno para mí:

<asp:Literal ID="emptyDataRowCnt" runat="server" Visible='<%# MyRepeater.Items.Count == 0 %>'> <li class="row emptyDataRow">No data here</li> </asp:Literal>

0

Usando las propiedades visibles y literales asp proporcionados en las respuestas anteriores, extendí la respuesta de erionpc ya sea a mostrar un 'no hay datos' o número de registros.

<FooterTemplate> 
       <asp:Literal ID="repeaterEmptyDataRow" runat="server" Visible='<%# Results_Repeater.Items.Count == 0 %>'> 
        <tr> 
         <td>No Data Found</td>  
        </tr> 
       </asp:Literal> 
       <asp:Literal ID="repeaterResultsDataRow1" runat="server" Visible='<%# Results_Repeater.Items.Count != 0 %>'> 
        <tr> 
         <td> 
       </asp:Literal> 
       <asp:Literal ID="repeaterResultsDataRow2" runat="server" Visible='<%# Results_Repeater.Items.Count != 0 %>' Text='<%# String.Concat(Results_Repeater.Items.Count.ToString(), " records.") %>' /> 
       <asp:Literal ID="repeaterResultsDataRow3" runat="server" Visible='<%# Results_Repeater.Items.Count != 0 %>'> 
         </td> 
        </tr> 
       </asp:Literal> 
       </table> 
      </FooterTemplate> 

No escribo mucho ASP, por lo que quizás haya una manera más clara de hacerlo.

+0

¿Qué es *** Results_Repeater ***? –

1

Se puede utilizar una plantilla de pie de página para administrar el masaje, como este

Paso 1

<FooterTemplate> 
    <%-- Label used for showing Error Message --%> 
    <asp:Label ID="lblDefaultMessage" runat="server" Text="Sorry, no item is there to show." Visible="false"> 
    </asp:Label> 
</FooterTemplate> 

Paso visibilidad 2

Mango de lable en caso Repeater_ItemDataBound como

protected void Repeater_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
if (Repeater.Items.Count < 1) 
    { 
    if (e.Item.ItemType == ListItemType.Footer) 
    { 
     Label lblDefaultMessage= (Label)e.Item.FindControl("lblDefaultMessage"); 
     lblDefaultMessage.Visible = true; 
    } 
    } 
} 
0

La mejor manera que he encontrado para resolver esto:

  1. Añadir la siguiente etiqueta en cualquier lugar de la página -

    <asp:Label ID="lblEmptyRepeater" runat="server" Visible="false" Text="There are no items in this repeater"></asp:Label> 
    
  2. Añadir la OnPreRenderEvent para su repetidor

    <asp:Repeater ID="emptyRepeater" runat="server" OnPreRender="emptyRepeater_PreRender"> 
    
  3. Ahora Dentro de este evento en su código subyacente, escriba el código

    protected void emptyRepeater_PreRender(object sender, EventArgs e) 
    { 
        lblEmptyRepeater.Visible = (emptyRepeater.Items.Count==0); 
    } 
    
  4. Ahora su repetidor vacío debe comprobarse después de que los datos estén encuadernados, pero antes de representarlos en la página, y mostrar la etiqueta si está vacía.

28

Otra posibilidad:

<FooterTemplate> 
    <asp:Label ID="lblEmptyData" runat="server" Visible='<%# ((Repeater)Container.NamingContainer).Items.Count == 0 %>' Text="No items found" /> 
</FooterTemplate> 

El beneficio de este fragmento de código es que no dependen de la ID que asignó a su repetidor.

+0

Si en 'FooterTemplate' tengo''? –

+1

@ PreguntonCojoneroCabrón: prueba esto: breez

Cuestiones relacionadas