65.9K
CodeProject 正在变化。 阅读更多。
Home

用于 ASP.NET 的分组 Repeater 控制

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.62/5 (19投票s)

2004 年 2 月 19 日

2分钟阅读

viewsIcon

299656

downloadIcon

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;
    }
   }
  }
 }
}

就这样了! 希望对您有所帮助。

© . All rights reserved.