Monday 29 November 2010

Vertical GridViews in ASP.net - Part 2c: Plumbing in the custom rendering

Now, as promised, how to plumb in the custom rendering code for the cell level rendering:

The key function you will need to work in is an override to the RenderChildren function in your inherited gridview (protected override void  RenderChildren(HtmlTextWriter writer)).

First off, you need to create a dictionary of your custom row renderers, one for each row in the controls Rows collection (of type GridViewRowCollection), indexed by the original row id (or a list of them in the same order as the original collection. As set up previously, the 'row renderer' is constructed by passing in the gridviewrow.

As you're overriding the child controls the one drawback is that you have to manually set up that table, using the htmlwriter to output the various rendering parameters:

 if(this.BorderWidth != null)
     writer.AddAttribute(HtmlTextWriterAttribute.Border, this.BorderWidth.ToString());
 writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, this.CellSpacing.ToString());
 writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, this.CellPadding.ToString());
 if (this.CssClass != null)
     writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass.ToString());

 writer.RenderBeginTag(HtmlTextWriterTag.Table);

then the important bit - for the moment we'll go with the simplified case that you are displaying all your datarows in one long row (I'll cover wrapping in a future post).

Firstly, iterate over the columns in the GridView's Columns collection (of type DataControlFieldCollection) - there is one entry in this collection for every field (BoundField,TemplateField, etc.) specified in the markup using the gridview.

Within this loop you then need to:
 - Tell the html writer to write out the <TR> tag:

  
writer.RenderBeginTag(HtmlTextWriterTag.Tr);

 - Loop over the rows in renderer list/dictionary, and within that call your renderer's custom cell Render Method:

  Renderers[RowIndex].Render(writer, ColumnIndex, IsHeader);
 - Tell the htmlwriter to write out the closing </TR> tag:

  writer.RenderEndTag();

After the loops you then need to tell the html writer to write the closing </TABLE> tag with a final call to writer.RenderEndTag()


With the code detailed about you now have the full basic solution. I will post more on some additions that you will most likely want - wrapping, empty cell handling, and Custom CSS properties, all of which are used in the featured product grids on http://public.presalesadvisor.com/ - but hopefully this is enough to get you started.

No comments:

Post a Comment