.NET 1.0Visual Studio .NET 2003Windows 2003.NET 1.1Windows 2000Windows XP中级开发Visual StudioWindows.NETASP.NETC#
用于 ASP.NET 的分组 Repeater 控制






3.62/5 (19投票s)
2004 年 2 月 19 日
2分钟阅读

299656

4908
这个自定义的 Repeater 控制可以用来在输出中添加分组标题。
引言
你有没有想过为什么 ASP.NET 没有自带一个可以分组结果的 Repeater 控制? 我想过,并且决定自己尝试编写一个。
我见过其他解决这个问题的方案,但没有这个方案那么简单和优雅,这就是我决定分享它的原因。
背景
ASP.NET 自带的 Repeater
控制有一个非常酷的事件:ItemCreated
事件。 每当向控制的 Controls
集合中添加一个元素(或模板实例)时,都会触发此事件。
此外,ASP.NET SDK 中的示例演示向我展示了如何使用模板和数据绑定。 由于它在网上很多地方都有文档,所以我不会在这里重复它。 只需点击 Google 搜索 'Templated Databound Control ASP.NET',你就会看到足够的结果。
解决方案的第三部分包括提供一个自定义 Comparer
委托,该委托将比较 2 个未知类型的项目。
解决方案
我所做的是:
- 创建
System.Web.UI.WebControls.Repeater
类的子类。 - 捕获
ItemCreated
事件。 - 将一个
GroupTemplate
模板添加到控制中(除了ItemTemplate
之外)。 - 对于创建的每个项目,使用自定义
Comparer
将其与前一个项目进行比较。 - 如果它不同,则实例化模板并使用与当前
Item
相同的ItemData
对其进行数据绑定。 - 重写
CreateChildControls
方法以重置“最后一条记录”成员。
总之,我认为这是一个很好的 ASP.NET 控制子类化示例,我仍然想知道为什么这个控制没有包含在标准框架中。
这是代码。 它也包含在演示解决方案文件中(见上文)。
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.ComponentModel;
namespace GroupedRepeater.Controls
{
/// <summary>
/// Summary description for GroupingRepeater.
/// When another group is found, render an additional template.
/// </summary>
public class GroupingRepeater : System.Web.UI.WebControls.Repeater
{
private ITemplate _groupTemplate = null;
private IComparer _comparer = null;
private static object lastvalue = null;
public GroupingRepeater()
{
this.ItemCreated += new
RepeaterItemEventHandler(GroupingRepeater_ItemCreated);
}
protected override void AddParsedSubObject(object obj)
{
base.AddParsedSubObject (obj);
}
public IComparer Comparer
{
get { return _comparer; }
set { _comparer = value; }
}
[TemplateContainer(typeof(GroupHeader))]
public ITemplate GroupTemplate
{
get
{
return _groupTemplate;
}
set
{
_groupTemplate = value;
}
}
protected override void CreateChildControls()
{
lastvalue = null;
base.CreateChildControls ();
}
private void GroupingRepeater_ItemCreated(object sender,
RepeaterItemEventArgs e)
{
System.Diagnostics.Trace.WriteLine(e.Item.GetType().Name);
if(e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
if(e.Item.DataItem != null)
{
if(_comparer.Compare(lastvalue, e.Item.DataItem) != 0)
{
//add a header if it was different from the previous item.
GroupHeader item = new GroupHeader();
_groupTemplate.InstantiateIn(item);
item.DataItem = e.Item.DataItem;
this.Controls.Add(item);
item.DataBind();
}
}
lastvalue = e.Item.DataItem;
}
}
public class GroupHeader : Control,INamingContainer
{
private object _dataItem;
public virtual object DataItem
{
get
{
return _dataItem;
}
set
{
_dataItem = value;
}
}
}
}
}
就这样了! 希望对您有所帮助。