After searching long and far for a Repeater control that would do exactly what I needed, I came up short. So, I did what any developer with too much time on their hands and no money to spend would do - I made my own.
What really got me started on this was Rob van der Veer's article, "A Grouping Repeater Control for ASP.NET". I used his
GroupingRepeater code as a starting point for my own code. Thanks Rob!
More often than not, I have found that I need a Repeater that is able to handle database results returned by queries with multiple
join statements. We all know that a
join statement can produce repetitive information. While Rob's article was a great starting point, his control had one major flaw: what if there is more than one "category" of unique repeating data?
In order to be able to implement the type of features, this control is much more complex. The way it works is this: instead of only one
GroupTemplate, there are as many as needed. Much can be explained by seeing an example of what the templates would look like.
Note: The "
HeaderTemplate" and "
ItemTemplate" tags are incorrectly capitalized and/or spaced due to a conflict with the way this page is rendered.
<uc1:GroupingRepeater ID="Items" Runat="Server">
<%# ((GroupingRepeater)Container.Parent).GroupData("Comments") %>
<%# DataBinder.Eval(Container.DataItem, "OrderDate") %> -
<%# DataBinder.Eval(Container.DataItem, "OrderID") %>:
$<%# DataBinder.Eval(Container.DataItem, "OrderAmount") %>
<%# DataBinder.Eval(Container.DataItem, "EmployeeName") %> on
<%# DataBinder.Eval(Container.DataItem, "CommentPostedDate") %>:
<%# DataBinder.Eval(Container.DataItem, "Comment") %>
<GroupIdentifier Index="-1" Key="ItemTemplate" Field="ID" />
<GroupIdentifier Index="0" Key="OrderHistory" Field="OrderID" />
<GroupIdentifier Index="1" Key="Comments" Field="CommentID" />
<SeparatorIdentifier Index="0" Key="ItemTemplate" />
<SeparatorIdentifier Index="1" Key="Comments" />
Now, some explanation
Since you've seen the example, now I'll explain how to set up your template code.
These templates work just as they do in the standard ASP.NET
This template is not supported in this version of the code. Sorry, I got lazy!
This template works mostly just like the
ItemTemplate in the standard ASP.NET
Repeater. The exception is that you have to identify the areas that will have the grouped items. You do this by using this code:
<%# ((GroupingRepeater)Container.Parent).GroupData("GroupKey") %>
GroupKey" should be replaced by whatever key you assign to that group in the corresponding
GroupIdentifier, which I will explain below.
Use these templates to set up your various groups. These are used just like any
ITemplate property, except that you can have as many as you like.
If you like, you can specify a
SeparatorTemplate to be used between
ItemTemplate items, and as many of your
GroupTemplates as you like. If a
SeparatorTemplate is specified for the
ItemTemplate or a
GroupTemplate, it will automatically be placed between each item.
TemplateIdentifier control allows the
GroupingRepeater to implement multiple templates by associating a developer-friendly "key" with the index location of the template.
GroupIdentifier templates are used to associate and identify which
GroupTemplates are used where. For example:
<GroupIdentifier Index="1" Key="Comments"
Field="CommentID" EmptyGroupDataText="(No Comments)" />
TemplateIdentifier would identify a
GroupTemplate that will be referenced by the key "
Comments", and is the second
GroupTemplate listed in the repeater control (the "
Index" is zero-based). The "
Field" property specifies which field of the
DataSource determines when a new group item should be created. If the value of this field is already present in the group items, the row will be skipped. The "
EmptyGroupDataText" property specifies what text should be rendered in the event that there is no data to display. If this property is not specified, nothing is displayed in that situation.
Note: You must have a
Index property is set to "-1" and whose
Key property is set to "
Field property for this identifier determines when a new
ItemTemplate item is to be created.
Note: You must specify a
GroupIdentifier for each
SeparatorIdentifer works much like the
GroupIdentifer, except that the
EmptyGroupDataText properties are not displayed. As with the
GroupIdentifier, you must specify a
SeparatorIdentifier for each
SeparatorTemplate specified. However, you are not required to specify a
And that's about it!
I hope you find this useful. Please note that I haven't done any terribly extensive debugging, but I will be updating the code as I make my own tweaks. Good luck, and enjoy!
Zounds, an update!
09 February 2006
Many people have posted requests in the comments for a working demo. Well, ask and ye shall receive - a demo is now available in the downloads section at the top of the page. It doesn't look too pretty, but it should give you a good idea of how this thing works and what it is capable of. Also, I've added an entire C#.NET project to the source file, including compiled binaries, to the source download. Enjoy!