Как я могу скрыть повторитель в ASP.NET C #, если источник данных не содержит элементов?
Вопрос
У меня есть ASP.NET страница, которая использует повторитель, вложенный в другой повторитель, для генерации списка данных.Это приводит к следующему:
<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>
В исходном коде (C #) я в основном использую LINQ для извлечения списка информации из XML-документа и привязки этой информации к первому повторителю.
В поисках ответа на этот вопрос, кажется, метод заключается в том, чтобы определить, являются ли данные для вложенного повторителя пустыми.Если это так, то вы устанавливаете видимость ретранслятора в значение false.
К сожалению, я не смог определить, как сделать это встроенным, а не в коде (поскольку это не обязательно будет работать для того, что я делаю).
Поскольку мои страницы сейчас не проверяются, потому что ul становится пустым для любых элементов без Data2, и поскольку я хотел бы продолжать использовать неупорядоченный список, я обращаюсь к вам за помощью.
Есть какие-нибудь идеи?
Спасибо!
Обновить:
Если это поможет, поскольку это вполне можно было бы сделать в исходном коде, LINQ - это что-то для этого:
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();
Решение
Этого не будет скрыть repeater полностью, но вы можете подклассировать элемент управления Repeater, чтобы он включал пустой шаблон данных, подобный 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 );
}
}
}
Вы можете использовать его в своем .aspx следующим образом:
<custom:EmptyCapableRepeater runat="server" ID="rptSearchResults">
<ItemTemplate>
<%# Eval( "Result" )%>
</ItemTemplate>
<SeparatorTemplate>
<br />
</SeparatorTemplate>
<EmptyDataTemplate>
<em>No results were found.</em>
</EmptyDataTemplate>
</custom:EmptyCapableRepeater>
Другие советы
Попробуйте что-то вроде:
<asp:Repeater runat="server" DataSource='<%#Eval("Data2")%>'
Visible='<%# ((IEnumerable)Eval("Data2")).GetEnumerator().MoveNext() %>'>
для вложенного ретранслятора
Почему бы не использовать ListView?Он предлагает большую часть той же функциональности, включая EmptyDataTemplate.
используй это:
protected void Repeater1_PreRender(object sender, EventArgs e)
{
if (Repeater1.Items.Count < 1)
{
container.Visible = false;
}
}
Когда вы выполняете свой запрос LINQ, проверьте его свойство Count (предоставляя ему какой-то список).Если его значение равно 0, то просто измените свойство Visible на false .
Насколько я знаю, вы должны сделать это через codebehind, просто используйте событие ItemDataBound для обработки этого, вы можете оставить практически все как есть, просто введите некоторую логику, которая получает dataset и определяет, есть ли в нем записи, если нет, скройте повторитель.
Я не думаю, что то, что вы делаете, сработает, я получаю сообщение об ошибке, когда пытаюсь установить источник данных так, как вы пытаетесь сделать;однако в коде, лежащем в основе, вы делаете это:
Предполагая, что вы добавили прослушиватель в ItemDataBoundEvent вашего родительского ретранслятора, тогда вам нужно будет немного изменить свой запрос linq, чтобы не использовать анонимный тип (создайте защищенный класс с вашими свойствами), в любом случае я использую dto в качестве имени класса.
void rep1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater rep2 = (Repeater)e.Item.FindControl("rep2");
rep2.DataSource = ((dto)e.Item.DataItem).y;
rep2.DataBind();
}
Я бы с удовольствием узнал, почему вы думаете, что не можете решить это в коде, лежащем в основе.
Я знаю, что это старая тема, и приведенный выше ответ - очень хорошее решение, но у меня была похожая проблема, и я нашел другое, очень простое решение, которым, как я думал, я тоже поделюсь.Это проверяет просто отлично и отображает то же самое.
Просто измените свой шаблон нижнего колонтитула на:
<FooterTemplate>
<li style="display:none;">This will not show.</li></ul>
</FooterTemplate>
Или если вы используете таблицы:
<FooterTemplate>
<tr> style="display:none;"><td>But something must be in here.</td></tr></table>
</FooterTemplate>
Надеюсь, это кому-нибудь поможет!
В OnItemDataBound
событие, установите для видимости значение false, если ItemType
является Header
и установите видимость в значение true , если ItemType
является Item
.