2011-03-11 4 views
41

Используя VS 2008, у меня есть элемент управления Repeater:Текст по умолчанию для управления пустой Repeater

<asp:Repeater runat="server" ID="storesRep" DataSourceID="storeSqlDataSource" 
    OnItemDataBound="StoresRep_ItemDataBound"> 
    <ItemTemplate> 
     <table style="padding:0px"> 
     <tr> 
      <td style="width:200px"><asp:Label ID="infoLbl" runat="server"> 
       Choose stores for upload:</asp:Label>&nbsp;&nbsp;&nbsp;&nbsp; 
      </td> 
      <td style="width:110px"> 
       <asp:Label ID="storeLbl" runat="server" Text='<%# Bind("Name") %>'> 
       </asp:Label>&nbsp;&nbsp; 
      </td> 
      <td><asp:CheckBox runat="server" ID="storeCheck" /></td> 
     </tr> 
     </table> 
    </ItemTemplate> 
</asp:Repeater> 
<asp:SqlDataSource ID="storeSqlDataSource" runat="server" 
    ConnectionString="<%$ ConnectionStrings:someConnectionString %>" 
    SelectCommand="SELECT [StoreId], [Name] FROM [Store] Order By [Name]"> 
</asp:SqlDataSource> 

Теперь я хотел бы, чтобы отобразить текст по умолчанию, как «Нет магазинов не найдено», если источник данных не возвращает элементы из базы данных. До сих пор я в основном использовал GridView, где у меня не было проблем из-за атрибута EmptyDataText.

ответ

26

Вы могли обойти тот факт, что Repeater не поддерживает встроенный способ сделать то, что вы делаете с помощью FooterTemplate в сочетании с OnItemDataBound события и показывая колонтитул только тогда, когда источник данных не возвращает элементов.

Примеры о том, как вы можете это сделать, можно найти по адресу:

Handling Empty Data in an ASP.NET Repeater control

How to show Empty Template in ASP.NET Repeater control?

+0

@marquito Если вам грустно о семантическом диссонансе, вы всегда можете использовать 'Panel' и показывать/скрывать это в' OnItemDataBound' вместо FooterTemplate ... – pseudocoder

+0

@pseudocoder печаль происходит из-за отсутствия выхода -of-the-box способ сделать это. Кроме того, я вынужден проверять каждый элемент данных, чтобы проверить, пуст ли конечный результат. Также должно быть событие OnFinishedDataBinding, которое предотвратило бы ненужные вызовы OnItemDataBound. – marquito

+0

Я смог успешно использовать этот подход после нескольких попыток с помощью разных методов. Я думаю, что использование 'panel' вместо' label' добавило бы еще большую гибкость, и я тоже с нетерпением жду этого. Спасибо, что поделились этим! –

62

Joaos ответ может даже быть упрощена. В сноске, не устанавливайте видимое-свойство вашего элемента по умолчанию лжи, но использовать следующее выражение:

<FooterTemplate> 
    <asp:Label ID="defaultItem" runat="server" 
     Visible='<%# YourRepeater.Items.Count == 0 %>' Text="No items found" /> 
</FooterTemplate> 

Таким образом, вы можете сохранить код позади.

+0

В каком элементе применяется свойство 'Visible'? –

-1

Если вы не хотите засорять ваш HTML со скрытыми элементами (я действительно не люблю потайные вещи с JS):

Вы, вероятно, уже есть статический класс Utils, который имеет статические свойства в нем. (Если нет, щелкните по решению и добавьте -> класс)

Установить общедоступную статическую строку, скрытую = ""; // на новый созданный Utils класса

На вашем коде позади .cs файла сделать это:

DataTable coll = .... 
if(coll.Rows.Count < 1) 
    Utils.hidden = "<span>Sorry, there were no items</span> 

Затем на вашем .ascx файле <FooterTemplate> выглядит следующим образом:

<FooterTemplate> 
    <%# Utils.hidden %> 
</FooterTemplate> 
5

Еще лучше : этот подкласс добавляет свойство EmptyDataTemplate. В вашей разметке введите элемент так же, как и элемент. По умолчанию это будет скрывать верхний и нижний колонтитулы, если нет данных; вы можете изменить это с помощью свойств HeaderVisibleWhenEmpty и FooterVisibleWhenEmpty в разметке.

public class RepeaterWithEmptyDataTemplate : Repeater 
{ 
    public virtual ITemplate EmptyDataTemplate { get; set; } 

    protected virtual bool DefaultHeaderVisibleWhenEmpty 
    { 
     get { return false; } 
    } 

    protected virtual bool DefaultFooterVisibleWhenEmpty 
    { 
     get { return false; } 
    } 

    public bool HeaderVisibleWhenEmpty 
    { 
     get { return ViewState["hve"] == null ? DefaultHeaderVisibleWhenEmpty : (bool) ViewState["hve"]; } 
     set { ViewState["hve"] = value; } 
    } 

    public bool FooterVisibleWhenEmpty 
    { 
     get { return ViewState["fve"] == null ? DefaultFooterVisibleWhenEmpty : (bool) ViewState["fve"]; } 
     set { ViewState["fve"] = value; } 
    } 

    protected override void OnDataBinding(EventArgs e) 
    { 
     base.OnDataBinding(e); 
     if (Items.Count == 0 && EmptyDataTemplate != null) 
     { 
      var emptyPlaceHolder = new PlaceHolder {ID = "empty", Visible = true}; 
      EmptyDataTemplate.InstantiateIn(emptyPlaceHolder); 

      //figure out where to put placeholder 
      RepeaterItem footer = 
       Controls.OfType<RepeaterItem>().FirstOrDefault(i => i.ItemType == ListItemType.Footer); 
      if (footer == null) 
      { 
       //add to end if no footer 
       Controls.Add(emptyPlaceHolder); 
      } 
      else 
      { 
       Controls.AddAt(Controls.IndexOf(footer), emptyPlaceHolder); 
      } 

      //hide header and footer according to properties. 
      foreach (RepeaterItem x in Controls.OfType<RepeaterItem>()) 
      { 
       switch (x.ItemType) 
       { 
        case ListItemType.Header: 
         x.Visible = HeaderVisibleWhenEmpty; 
         break; 
        case ListItemType.Footer: 
         x.Visible = FooterVisibleWhenEmpty; 
         break; 
       } 
      } 
     } 
    } 
} 

образца в разметке:

<myprefix:RepeaterWithEmptyDataTemplate runat=server> 
    <ItemTemplate>blah blah blah</ItemTemplate> 
    <EmptyDataTemplate>Hey, no data!</EmptyDataTemplate> 
</myprefix:RepeaterWithEmptyDataTemplate> 

Пожалуйста, обратите внимание, что метод DataBind должен быть вызван, или не будет отображаться EmptyDataTemplate.

0

На основании ответа n. 3 я принял следующее решение, которое, кажется, достаточно хорошо для меня:

<asp:Literal ID="emptyDataRowCnt" runat="server" Visible='<%# MyRepeater.Items.Count == 0 %>'> <li class="row emptyDataRow">No data here</li> </asp:Literal>

0

Используя видимые свойства и осины литералы, представленные в предыдущих ответах, я протянул ответ erionpc, чтобы либо не отображать «нет данных» или количества записей.

<FooterTemplate> 
       <asp:Literal ID="repeaterEmptyDataRow" runat="server" Visible='<%# Results_Repeater.Items.Count == 0 %>'> 
        <tr> 
         <td>No Data Found</td>  
        </tr> 
       </asp:Literal> 
       <asp:Literal ID="repeaterResultsDataRow1" runat="server" Visible='<%# Results_Repeater.Items.Count != 0 %>'> 
        <tr> 
         <td> 
       </asp:Literal> 
       <asp:Literal ID="repeaterResultsDataRow2" runat="server" Visible='<%# Results_Repeater.Items.Count != 0 %>' Text='<%# String.Concat(Results_Repeater.Items.Count.ToString(), " records.") %>' /> 
       <asp:Literal ID="repeaterResultsDataRow3" runat="server" Visible='<%# Results_Repeater.Items.Count != 0 %>'> 
         </td> 
        </tr> 
       </asp:Literal> 
       </table> 
      </FooterTemplate> 

Я не пишу много asp, так что, возможно, более чистый способ сделать это.

+0

Что такое *** Results_Repeater ***? –

1

Вы можете использовать шаблон колонтитула для управления массаж, как этот

Шаг 1

<FooterTemplate> 
    <%-- Label used for showing Error Message --%> 
    <asp:Label ID="lblDefaultMessage" runat="server" Text="Sorry, no item is there to show." Visible="false"> 
    </asp:Label> 
</FooterTemplate> 

Шаг 2

Handle видимость звукозаписывающей компанией в Repeater_ItemDataBound события как

protected void Repeater_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
if (Repeater.Items.Count < 1) 
    { 
    if (e.Item.ItemType == ListItemType.Footer) 
    { 
     Label lblDefaultMessage= (Label)e.Item.FindControl("lblDefaultMessage"); 
     lblDefaultMessage.Visible = true; 
    } 
    } 
} 
0

Лучший способа я нашел, чтобы решить эту проблему:

  1. Добавьте следующую метку в любом месте на странице -

    <asp:Label ID="lblEmptyRepeater" runat="server" Visible="false" Text="There are no items in this repeater"></asp:Label> 
    
  2. Добавьте OnPreRenderEvent для повторителя

    <asp:Repeater ID="emptyRepeater" runat="server" OnPreRender="emptyRepeater_PreRender"> 
    
  3. сейчас внутри этого события в вашем коде, напишите код

    protected void emptyRepeater_PreRender(object sender, EventArgs e) 
    { 
        lblEmptyRepeater.Visible = (emptyRepeater.Items.Count==0); 
    } 
    
  4. Теперь ваш пустой ретранслятор должен быть проверен после того, как данные привязаны, но перед визуализацией на странице, и покажите этикетку, если она пуста.

28

Другая возможность:

<FooterTemplate> 
    <asp:Label ID="lblEmptyData" runat="server" Visible='<%# ((Repeater)Container.NamingContainer).Items.Count == 0 %>' Text="No items found" /> 
</FooterTemplate> 

Преимущество этого фрагмента кода является то, что вы не зависит от идентификатора, назначенное для ретранслятора.

+0

Если в 'FooterTemplate' у меня есть' '? –

+1

@ PreguntonCojoneroCabrón: попробуйте следующее: <жерех: Буквенный Runat = "сервер" Visible = '<% # ((ретранслятор) Container.NamingContainer) .Items.Count == 0%>'> breez

Смежные вопросы