Como posso ocultar um repetidor em ASP.NET C # se o DataSource não contém itens?
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();
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
.