This project has moved and is read-only. For the latest updates, please go here.

Customizing the way your reports are rendered

DoddleReport automatically picks up on certain attributes on your model, specifically the Data Annotations attributes.

If you put a [Display(Name = "Product Name")] on top on your property, DoddleReport will use that customized name when rendering the property on the report.

Additionally, there are 4 ways to further customize your reports.

  • Render Hints
  • Text Fields
  • Data Fields
  • RenderingRow event


// Render Hints
report.RenderHints.Orientation = ReportOrientation.Landscape;
report.RenderHints.BooleanCheckboxes = true;

// Text Fields
report.TextFields.Title = "Products Report";
report.TextFields.Footer = "Copyright 2009 © The Doddle Project";
report.TextFields.Header = string.Format("Report Generated: {0}", DateTime.Now);
report.TextFields["HtmlLogo"] = "<img src='' />";

// Data Fields
report.DataFields["ProductID"].Hidden = true;
report.DataFields["CategoryID"].Hidden = true;
report.DataFields["SupplierID"].Hidden = true;
report.DataFields["ProductName"].HeaderText = "Product";
report.DataFields["UnitPrice"].DataFormatString = "{0:C}";
report.DataFields["UnitPrice"].ShowTotals = true;
report.DataFields[0].DataStyle.BackColor = Color.Maroon;
report.DataFields[0].DataStyle.ForeColor = Color.White;

// Advanced customization with a callback delegate 
report.DataFields["OutOfStock"].FormatAs<bool>(value => value ? "Yes" : "No");


Text Fields will be used by the Report Writers to supply key textual fields to a report writer.

The default TextFields are as follows:

  • Title - specify the page title
  • Header - specify additional page header information
  • Footer - specify the page footer

All Report Writers should understand how to write those 3 primary fields, but they can also go beyond that. The TextFields property also supports an indexer overload to set custom TextFields that only certain ReportWriters will interpret. This will allow you to use the same Report for a variety of writers.

In the example above you will notice I used a report.TextFields["HtmlLogo"] = "<img src='' />"; -- this is a custom TextField named "HtmlLogo" that only the HtmlReportWriter will be looking for. When the HtmlReportWriter begins render a report that specifies a custom HtmlLogo TextField it will append the image URL to its HTML output, allowing simple and flexible customization of the rendering with minimal work.


Data Fields represent the columns of data written to the report. They are accesses via an indexer and allow customization via the following properties:

  • Hidden - hides a field from the report
  • HeaderText - specify custom header text for the column
  • ShowTotals - if a numeric column and set to true, this will automatically append a Totals Footer under the column
  • DataFormatString - specify a custom DataFormatString to write the data ("{0:C}" will format currency for example)
  • DataStyle - specify the Style of the data rows for this column
  • HeaderStyle - specify the Style of the header row for this column
  • FooterStyle - specify the Style of the footer row for this column


Render Hints are used to supply custom data that will be passed to ReportWriters giving them some additional insight in how you want your report to appear.

The default RenderHints are as follows:

  • Orientation - specify whether you want you report to appear Portrait or Landscape
  • BooleanCheckboxes - indicate that you want your report to render boolean fields as checkboxes

The RenderHints property behaves exactly like the TextFields property in that it supports an indexer to pass in custom RenderHints to the report writers.

In the example above you will notice I used a report.RenderHints["HtmlStyle"] = "p { font-size: 14px; }"; -- this is a custom RenderHint that only the HtmlReportWriter will be looking for, and when it writes a report that specifies a custom HtmlStyle it will append that style declaration to its HTML output, allowing simple and flexible customization of the rendering with minimal work.

RenderingRow Event

For maximum flexibility you can subscribe to the RenderingRow event and add per-row rendering logic to your report.

// Subscribe
report.RenderingRow += new EventHandler<ReportRowEventArgs>(report_RenderingRow);
// Add logic
void report_RenderingRow(object sender, ReportRowEventArgs e)
    if (e.Row.RowType == ReportRowType.DataRow)
        decimal unitPrice = (decimal) e.Row["UnitPrice"];
        if (unitPrice < 10)
            e.Row.Fields["UnitPrice"].DataStyle.Bold = true;

Last edited Aug 29, 2012 at 7:34 PM by mhidinger, version 8


talleyouro May 21, 2015 at 8:58 PM 
Thank You

farrukhsubhani Dec 22, 2011 at 8:32 PM 
Nice Work Mhidinger, How can we know what CustomTypes HTMLReportWriter will be looking for?. Also can you give an example to style alternate rows as this will make a report more readable.