Как я могу скрыть повторитель в ASP.NET C #, если источник данных не содержит элементов?

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

  •  11-07-2019
  •  | 
  •  

Вопрос

У меня есть 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top