Comment masquer un répéteur dans ASP.NET C # si la source de données ne contient aucun élément?

StackOverflow https://stackoverflow.com/questions/327151

  •  11-07-2019
  •  | 
  •  

Question

J'ai une page ASP.NET qui utilise un répéteur imbriqué dans un autre répéteur pour générer une liste de données. C'est à l'effet de ce qui suit:

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

Dans le code-behind (C #), j'utilise essentiellement LINQ pour extraire une liste d'informations d'un document XML et la lier au premier répéteur.

En cherchant la réponse, il semble que la méthode consiste à déterminer si les données du répéteur imbriqué sont vides. Si tel est le cas, vous définissez la visibilité du répéteur sur false.

Malheureusement, je n'ai pas été en mesure de déterminer comment faire cela en ligne, et non dans le code-behind (car cela ne fonctionnera pas nécessairement pour ce que je fais).

Étant donné que mes pages ne sont plus validées, car ul finit par être vide pour tous les éléments sans Data2, et parce que j'aimerais continuer à utiliser une liste non ordonnée, je sollicite votre aide.

Des idées?

Merci!

MISE À JOUR:

Si cela vous aide, étant donné que cela pourrait très bien être fait dans le code-behind, le LINQ répond à cet effet:

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();
Était-ce utile?

La solution

Ceci ne pas cacher le répéteur, mais vous pouvez sous-classer le contrôle Repeater afin qu'il inclue un modèle de données vide de type GridView:

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

Vous pouvez les utiliser dans votre .aspx comme ceci:

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

Autres conseils

Essayez quelque chose comme:

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

pour le répéteur imbriqué

Pourquoi ne pas utiliser un ListView? Il offre une grande partie des mêmes fonctionnalités, notamment un EmptyDataTemplate.

utiliser ceci:

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

Une fois votre requête LINQ exécutée, vérifiez sa propriété Count (en lui fournissant une liste). Si sa valeur est 0, il suffit de transformer la propriété Visible en false.

Autant que je sache, vous devez le faire via le code ci-dessous, utilisez simplement l'événement ItemDataBound pour le gérer, vous pouvez laisser à peu près tout ce qu'il est, entrez simplement une logique qui récupère l'ensemble de données et détermine s'il contient des entrées, sinon masquer le répéteur.

Je ne pense pas que ce que vous ferez va fonctionner, je reçois une erreur lorsque j'essaie de définir DataSource comme vous essayez de le faire. cependant, dans le code derrière vous faites ceci:

En supposant que vous ayez ajouté un écouteur à ItemDataBoundEvent de votre répéteur parent, vous devrez modifier légèrement votre requête linq pour ne pas utiliser un type anonyme (créer une classe protégée contenant vos propriétés). Dans ce cas, j'utilise dto comme classe. prénom.

void rep1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{

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

J'aimerais savoir pourquoi vous pensez que vous ne pouvez pas résoudre ce problème dans le code situé derrière.

Je sais que c’est un vieux fil et la réponse ci-dessus est une très bonne solution, mais j’avais un problème similaire et j’ai trouvé une autre solution simple et variée que je pensais partager. Cela valide très bien et affiche le même.

Modifiez simplement votre modèle de pied de page en:

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

Ou si vos tables d'utilisation:

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

J'espère que cela aide quelqu'un!

Dans l'événement OnItemDataBound , définissez la visibilité sur false si ItemType est un en-tête et définissez la visibilité sur True si ItemType est un élément .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top