web-dev-qa-db-fra.com

Texte par défaut pour le contrôle de répéteur vide

En utilisant VS 2008, j'ai un contrôle Repeater:

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

Maintenant, j'aimerais afficher un texte par défaut du type "Aucun magasin trouvé" si la source de données ne renvoie aucun élément de la base de données. Jusqu'à présent, j'ai principalement utilisé GridView où je n'avais pas de problèmes à cause de l'attribut EmptyDataText.

42
AGuyCalledGerald

Vous pouvez contourner le fait que Repeater ne prend pas en charge un moyen intégré d'accomplir ce que vous faites en utilisant FooterTemplate conjointement avec l'événement OnItemDataBound et en affichant le pied de page uniquement lorsque la source de données ne renvoie aucun élément.

Vous trouverez des exemples de ce que vous pouvez faire à l’adresse suivante:

Gestion des données vides dans un contrôle ASP.NET Repeater

Comment afficher un modèle vide dans le contrôle ASP.NET Repeater?

27
João Angelo

Joaos réponse peut même être simplifiée. Dans le pied de page, ne définissez pas la propriété visible de votre élément par défaut sur false, mais utilisez l'expression suivante:

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

De cette façon, vous pouvez enregistrer le code derrière.

65
AGuyCalledGerald

Une autre possibilité:

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

L'avantage de cet extrait de code est que vous ne dépendez pas de l'ID que vous avez attribué à votre répéteur.

28
breez

Encore mieux: cette sous-classe ajoute une propriété EmptyDataTemplate. Dans votre balisage, insérez un élément comme vous le feriez d'un élément. Par défaut, l'en-tête et le pied de page seront masqués s'il n'y a pas de données. vous pouvez modifier cela avec les propriétés HeaderVisibleWhenEmpty et FooterVisibleWhenEmpty dans le balisage.

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

Échantillon dans le balisage:

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

Veuillez noter que la méthode DataBind doit être appelée, sinon le modèle emptyd ne sera pas affiché.

5
Xavier J

Vous pouvez utiliser un modèle de pied de page pour gérer le massage, comme ceci

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

Étape 2

Gérer la visibilité de lable dans l'événement Repeater_ItemDataBound comme

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;
    }
  }
}
1
Nitin Singh

Sur la base de la réponse n. 3 j’ai adopté la solution suivante qui me semble assez bonne: 

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

0
erionpc

Le meilleur moyen que j'ai trouvé pour résoudre ceci:

  1. Ajoutez l'étiquette suivante n'importe où sur votre page - 

    <asp:Label ID="lblEmptyRepeater" runat="server" Visible="false" Text="There are no items in this repeater"></asp:Label>
    
  2. Ajoutez le OnPreRenderEvent pour votre répéteur

    <asp:Repeater ID="emptyRepeater" runat="server" OnPreRender="emptyRepeater_PreRender">
    
  3. Maintenant, à l'intérieur de cet événement dans votre codeBear, écrivez le code

    protected void emptyRepeater_PreRender(object sender, EventArgs e)
    {
       lblEmptyRepeater.Visible = (emptyRepeater.Items.Count==0);
    }
    
  4. Maintenant, votre répéteur vide doit être vérifié après la liaison des données mais avant le rendu sur la page, et affichez l'étiquette si elle est vide.

0
rohithrrao

En utilisant les propriétés visibles et les littéraux asp fournis dans les réponses précédentes, j'ai étendu la réponse de erionpc afin d'afficher un nombre de données «sans données» ou un nombre record d'enregistrements.

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

Je n'écris pas beaucoup d'asp, alors il y a peut-être une façon plus propre de le faire.

0
Scott