My question to everyone, Is the Repeater control dynamic
enough to create custom tables on the fly? When I think of dynamic it's
something you have complete control over. And can change the display at anytime
during execution. Please note that I'm
sure there are multiple ways one can accomplish what I'm looking for, this is
the way I choose to do it.
The one thing about the repeater control is it's great for
making data that has a unique predefined header and footer. The remaining data
can be found in the body ("ItemTemplate, AlternatingItemTemplate...")
and over all is dynamic. The data that is contained in the body is most of the
time very similar in Size and Type. This is because the DataSource of the
Repeater control takes any IEnumerable object. This IEnumerable object is a
data structure. This data structure is 90%+ of the time displayed to the screen
in a table or list because the developer knows what data that structure is
going to contain.
So now we have came to the conclusion that the repeater
control is great for creating Predefined templates, but when about when you
want to create Dynamic Templates on the fly. You're probably thinking that this
is easy; one just has to create a Template class that derives from ITemplate.
public class
SomeOnesTemplate : ITemplate
Inside this class if you don't create multiple template
classes (one for Header, Item, and footer) you will have to check the the ListItemType.Item in ITemplate.InstantiateIn and then
process the data. One will quickly get
this set up and get everything working in no time from here. But the templates
are still not completely dynamic because the HeaderTemplate and FooterTemplate are
not being passed any data.
In your custom Item templates you can do anything you want
with the DataRowView (If the DataSource is a DataView) or DataRow. The row of data is provided to you in your
custom template by the repeater control, except for the HeaderTemplate and
FooterTemplate.
Apparently Microsoft does not want the user to access any
rows of data, I can see their point, as in the row they would pass you would be
the first row of actual data, however why can't they pass you a row with the
column names? One can override this default behavior by implementing some more
code. But please consider another thing before doing this. Not only does the
HeaderTemplate not have access to any DataRow, All templates do not have access
to the DataSource. So even if there was not a row of data being sent, one also
does not have access to the DataSource.
I think one of the reasons why the user can't access the
DataSource inside any template is because .Net is iterating through the
DataSource, and they do not want the Data to become corrupted. Also another
point I would like to add. If one did implement it so you could get access to
the DataSource, you would want to clone the IEnumerable object, thus creating a
lot of overhead, because you're copying all the data for one simple operation.
So there is no really good way around this if you wish to create everything in
your Template class.
The Work Around
Here is one of the few ways there are to get around this
issue. Remove the HeaderTemplate from your Template Class and overload the
following methods:
protected override
void Render(HtmlTextWriter
writer)
public override
void DataBind()
You will
want to create your headers markup dynamically in the DataBind method and then
call base method of DataBind. You have full access to the DataSource, and from
here you can do anything with the data. You could have something like this
StringBuilder header = new StringBuilder();
header.Append("<table><tbody><tr>");
DataView dv =
DataSource as DataView;
if(dv != null)
{
foreach (DataColumn dc in
dv.Table.Columns)
{
header.Append(string.Format("<th
scope=\"col\">{0}</th>", dc.ColumnName));
}
header.Append("</tr>")
}
return header.ToString();
The next Step is to write the headers markup that you
created before the repeater controls Body ("Item") and footer templates run.
You can do this by adding the following code to the overridden Render method. HeaderMarkup is a property that stored the Header's html markup.
writer.Write(HeaderMarkup);
base.Render(writer);
And that is how you can create a Dynamic Repeater control,
to create custom templates. Now you can show or hide certain columns on the
fly.
Read the complete post at http://telliterns.com/blaken/archive/2007/07/31/repeater-control-is-it-really-that-dynamic.aspx
Posted
Jul 31 2007, 10:35 AM
by
Blake Niemyjski's Blog
|