4

有什么方法可以在数据绑定 asp:repeater 控件中的字段更改时显示子标题行,例如

代替

国家 | 颜色 | 数字
英国 | 红色 | 3
英国 | 绿色 | 3
法国| 家企业 红色 3

做这个:

==英国==
颜色 | 数字
红色 | 3
绿色 3
==法国==
颜色 | 数字
红色 | 3

非常感谢您的帮助。

4

5 回答 5

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;
    }
}
于 2009-02-03T14:31:26.967 回答
3

另一种解决方案是简单地使用两个中继器,一个嵌套在另一个中。您可以将带有子记录的组传递给第一个转发器,然后在组转发器的 ItemDataBound 上,将子记录传递给子转发器并在那里调用 DataBind()。

这是更多的代码,但实际上可以让您更好地控制布局,而无需在代码隐藏中使用 HTML 创建代码。

正如您在此处看到的,我们有一个父中继器,并且在项目模板中,我们可以根据需要自定义每个组。在 ChildRepeater 中,我们有我们的项目模板,我们可以在其中自定义分组内的每个项目。非常干净,并且全部带有声明性 UI。

<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 事件并按照您认为合适的方式将子项绑定到控件。

于 2009-02-04T11:27:49.677 回答
0

啊 - 你在一个分组中继器之后。我过去采用的解决方案似乎已经消失了。也许你能找到它。但无论如何,搜索分组中继器应该会有所帮助。

于 2009-02-03T14:22:12.740 回答
0

乔尔解决方案,我可以建议以下 - 改变这一行:

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

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

而且您可以从 .as?x 文件自定义外观。

于 2009-02-03T14:58:25.493 回答
0

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 纳粹更快乐。

于 2009-02-04T11:20:55.213 回答