asp:repeater - заголовки при изменении раздела

есть ли способ вывести строку подзаголовка при изменении поля в элементе управления asp:repeater с привязкой к данным, например.

Вместо

country | colour | number
uk | red | 3
uk | green | 3
france | red 3

Сделай это:

==UK==
colour | number
red | 3
green 3
==FRANCE==
colour | number
red | 3

Большое спасибо за любую помощь.


person ctrlalt3nd    schedule 03.02.2009    source источник


Ответы (5)


Встроенной поддержки нет, но это не значит, что это невозможно.

Вам нужно будет переопределить событие OnItemDataBound и иметь что-то вроде этого в разметке:

<asp:Repeater OnItemDataBound="NextItem" ... >
    <ItemTemplate><asp:Literal Id="Header" Visible="False" Text="{0}<strong>{1}</strong><br/><table>" ... />
         <tr>
             <td><asp:Label id="Color" Text="<%# Eval("Color")" ... /></td>
             <td><asp:Label id="Number" Text="<%# Eval("Number")" ... /></td>
         </tr>
    </ItemTemplate>
</asp:Repeater></table>

Затем в коде:

private string CurCountry = string.Empty;

private void NextItem(object sender, RepeaterItemEventARgs e)
{
    if ( e.Item.ItemType != ListItemType.Item 
      && e.Item.ItemType != ListItemType.AlternatingItem) return;

    DbDataRecord row = (DbDataRecord)e.Item.DataItem;

    if (CurCountry != row["country"].ToString() )
    {
        string prev = (CurCounter == string.Empty)?"":"</table>";
        CurCountry = row["country"].ToString();

        Literal header = (Literal)e.Item.FindControl("Header");
        Literal footer = (Literal)e.Item.FindControl("Footer");

        header.Text = string.Format(header.Text, prev, CurCountry);
        header.Visible = true;
    }
}
person Joel Coehoorn    schedule 03.02.2009

Другое решение состоит в том, чтобы просто использовать два повторителя, один из которых вложен в другой. Вы можете передать свои группы с дочерними записями первому повторителю, а на ItemDataBound повторителя групп передать дочерние записи дочернему повторителю и вызвать там DataBind().

Это больше кода, но на самом деле дает вам больше контроля над макетом без кода создания HTML в вашем коде.

Как вы можете видеть здесь, у нас есть родительский повторитель, и в шаблоне элемента мы можем настроить каждую группу по своему усмотрению. В ChildRepeater у нас есть шаблон элемента, в котором мы можем настроить каждый элемент внутри группы. Очень чистый и все с декларативным пользовательским интерфейсом.

<asp:Repeater runat="server" id="GroupRepeater">
 <ItemTemplate>
   <asp:Literal runat="server" id="HeaderText" />
   <asp:Repeater runat="server id="ChildRepeater">
    <ItemTemplate>
      <asp:Literal runat="server" id="InfoGoesHere" />
    </ItemTemplate>
   </asp:Repeater>
 </ItemTemplate>
</asp:Repeater>

В коде позади у нас может быть что-то вроде этого:

private void GroupRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
  //Get the child records, this can be any data structure you want
  SomeChildCollection children = ((SomeGroupCollection)e.Item.DataItem).Children;
  //Find the child repeater
  Repeater childRepeater = e.Item.FindControl("ChildRepeater") as Repeater;
  childRepeater.ItemDataBound += SomeMethod;
  childRepeater.DataSource = children;
  childRepeater.DataBind();
}

После привязки каждого дочернего элемента вы можете подписаться на событие ItemDataBound и выполнить привязку дочернего элемента к элементам управления по своему усмотрению.

person Ray Booysen    schedule 04.02.2009
comment
+1 к вложенным повторителям. В этой статье есть аналогичное пошаговое руководство, которое по сути совпадает с этим ответом, но может помочь другим: codeproject.com/KB/aspnet/AspNetNestedRepeaters.aspx - person bkaid; 23.10.2011

Для joel Solution могу посоветовать следующее - изменить эту строку:

header.Text = string.Format("<strong> {0} </strong><br/><table>", CurCountry);

to

header.Text = string.Format(header.Text, CurCountry);

Кроме того, вы можете настроить внешний вид из файла .as?x.

person st78    schedule 03.02.2009

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

person darasd    schedule 03.02.2009
comment
Привет, это то, что я ищу. - person ctrlalt3nd; 03.02.2009

Кажется, в коде dotnetjunkies есть несколько ошибок, но я нашел гораздо более простое решение здесь http://www.west-wind.com/weblog/posts/140753.aspx

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

<%# this.RenderGroup(Eval("Group") as
string) %> 

Выражение вызывает метод формы для отображения дополнительного тега div. Код этого простого метода выглядит так:

string LastGroup = "@#@~";
protected string RenderGroup(string Group) {   
    if (Group == this.LastGroup)       
    return "";     // *** Group has changed    
    this.LastGroup = Group;    
    return "<div class='groupheader'>" +Group + "</div>";
}

Этот код вызывается для каждого элемента и просто проверяет, изменилась ли группа. Если ничего не возвращается, в противном случае возвращается простой тег div в виде строки для встраивания в разметку. Я решил отправить обратно HTML, но я полагаю, что вы также можете вернуть true или false и условно отобразить элемент управления в Repeater, что сделает нацистов CSS более счастливыми.

person ctrlalt3nd    schedule 04.02.2009