C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  Update World C++: Сборник GPL QT исходников
  Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Дебетовая карта Home Credit [CPS] RU

 A Grouping Repeater Control for ASP.NET / Custom Controls / ASP. NET

Introduction

Have you ever wondered why ASP.NET did not come with a repeater control that can group results? Well, I did and I decided to try to write one myself.

I have seen other solutions to this problem, but not as simple and elegant as this one, and that is why I decided to share it.

Background

The Repeater control that comes with ASP.NET has one very cool event: the ItemCreated event. This event is fired whenever an element (or an instance of a template) is added to the Controls collection of the control.

Furthermore, the source demos in the ASP.NET SDK showed me how to use templates and data binding. Because it is documented in a lot of places on the web, I'm not going to repeat that here. Just hit Google with 'Templated Databound Control ASP.NET' and you'll see enough results.

The third part of the solution included the ability to provide a custom Comparer delegate that will compare 2 items of an unknown type.

The solution

What I did was the following:

  • Create a subclass of the System.Web.UI.WebControls.Repeater class.
  • Trap the ItemCreated event.
  • Add a GroupTemplate template to the control (in addition to the ItemTemplate).
  • For each item created, compare it to the previous item using a custom Comparer.
  • If it is different, instantiate the template and databind it using the same ItemData as the current Item.
  • Override the CreateChildControls method to reset the 'last record' member.

Anyway, I think this is a very good example of subclassing ASP.NET controls and I'm still wondering why this one isn't included in the standard framework.

Here's the code. It is also included in the demo solution file (see above).

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

That's it! I hope you find this useful.




Дебетовая карта Home Credit [CPS] RU