Como posso ocultar um repetidor em ASP.NET C # se o DataSource não contém itens?

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

  •  11-07-2019
  •  | 
  •  

Pergunta

Eu tenho uma página ASP.NET que usa um repetidor aninhados dentro de outro repetidor para gerar uma lista de dados. É para o efeito seguintes:

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

No (C #) code-behind eu estou basicamente usando LINQ para puxar uma lista de informações a partir de um documento XML e vincular essa informação para o primeiro repetidor.

Procurando a resposta para isso, parece que o método consiste em determinar se os dados para o repetidor aninhados está vazio. Se for, então você definir a visibilidade do repetidor como falsa.

Infelizmente, eu não tenho sido capaz de determinar como fazer isso em linha, e não no código-behind (uma vez que não vai necessariamente funcionar para o que estou fazendo).

Uma vez que minhas páginas não estão validando agora, porque as extremidades ul por ser vazio para todos os itens sem Data2, e porque eu gostaria de continuar usando uma lista não ordenada, busco sua ajuda.

Todas as idéias?

Obrigado!

UPDATE:

Se ajudar, uma vez que poderia muito bem ser possível fazer no código-behind, o LINQ é algo a este efeito:

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();
Foi útil?

Solução

Isto não Ocultar o repetidor completamente, mas você pode subclasse o controle Repeater para que ele inclui um GridView-como modelo de dados vazio:

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

Pode-los usá-lo em sua 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>

Outras dicas

Tente algo como:

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

para o repetidor aninhados

Por que não usar um ListView? Ele oferece grande parte da mesma funcionalidade incluindo um EmptyDataTemplate.

usar este:

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

Quando você começa sua consulta LINQ executado, verificar a sua propriedade Count (fornecendo sua uma lista de algum tipo). Se a sua 0, então é só virar a propriedade Visible para false.

Tanto quanto eu sei que você deve fazer isso através do codebehind, basta usar o evento ItemDataBound para lidar com isso, você pode deixar tudo muito bonito como é, simplesmente input alguma lógica que recebe o conjunto de dados e determina se ele tem entradas, se não esconder o repetidor.

Eu não acho que você está fazendo está indo trabalhar eu recebo um erro quando eu tento e definir a fonte de dados que você está tentando fazer; no entanto, no código atrás de você fazer isso:

Assumindo que você adicionou um ouvinte para ItemDataBoundEvent de sua repetidora pai, então você terá de alterar a sua consulta linq ligeiramente para não usar um tipo anônimo (Criar uma classe protegida que tem suas propriedades) No caso MJY Estou usando dto como a classe nome.

void rep1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{

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

Eu adoraria saber por que você acha que não pode resolver isso no trás código.

Eu sei que esta é uma discussão antiga e a resposta acima é uma solução muito bom, mas eu tive um problema semelhante e encontraram outra variar solução simples que eu pensei que iria partilhar também. Isso valida muito bem e exibe o mesmo.

Apenas mudar o seu modelo de rodapé para:

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

Ou se o seu usando tabelas:

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

Espero que ajude alguém!

No caso OnItemDataBound, conjunto de visibilidade para false se ItemType é um Header e conjunto de visibilidade para true se ItemType é um Item.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top