Wednesday, November 17, 2010

Условное отображение внутри Repeater

Задача заключается в том, чтобы отобразить часть данных внутри Repeater в зависимости от отображаемых данных. Например, нужно добавить кнопки действий в зависимости от некоторого поля Status. Самый простой вариант – использовать для этого специальный метод, примерно так:

<asp:Repeater ID="NotesRepeater" runat="server">
  <HeaderTemplate>
    <table class="list">
  </HeaderTemplate>
  <ItemTemplate>
    ....................................
    <%# GetButtonHTML(Eval("Status"))%>>
    ....................................
    </ItemTemplate>
    <FooterTemplate>
      </table>
    </FooterTemplate>
</asp:Repeater>

А метод GetButtonHTML описывается внутри кода страницы так:

public string GetButtonHTML(object status)
{
   Тут возвращаем HTML-код кнопки, проверяя status
   return “<button style=”ActionButtonStyle”>Удалить</button>”;
}

Метод плох тем, что в нем смешивается разметка и код, т.к. часть разметки попадает в код. Это мешает работе дизайнеров, усложняет изменение кода.

Мне понравится другой вариант, чуть более сложный, но зато четко разделяющий код и разметку.

Разметку, зависящую от некоторых условий, оборачиваем в PlaceHolder, а в сам элемент Repeater добавляем обработчик создания элементов:

<asp:Repeater ID="NotesRepeater" runat="server"
            OnItemDataBound="NotesRepeater_ItemDataBound">
  <HeaderTemplate>
    <table class="list">
  </HeaderTemplate>
  <ItemTemplate>
    ....................................
    <asp:PlaceHolder ID="ActionHolder"
                        Visible="false" runat="server">
       <button style=”ActionButtonStyle”>Удалить</button>
      </asp:PlaceHolder>
    </ItemTemplate>
    <FooterTemplate>
      </table>
    </FooterTemplate>
</asp:Repeater>

В обработчике создания элементов устанавливаем видимость ActionHolder в зависимости от нужных условий:

protected void NotesRepeater_ItemDataBound(object sender,
                          RepeaterItemEventArgs e)
{
  if (e.Item.ItemType == ListItemType.Item ||
           e.Item.ItemType == ListItemType.AlternatingItem)
  {
    Note item = e.Item.DataItem as Note;
    if (item == null)
     return;
     Control actionHolder =
                 e.Item.FindControl("ActionHolder");
     actionHolder.Visible = item.Status == 0;
  }
}

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

No comments: