Snips and snails and puppy dog tails: what little polygons are made of

When I wrote about the genesis of XMLRSDocs-RDLDocumenter I credited Teo Lachev’s MSDN article and its ProgressBarCRI sample as a source of inspiration and code samples for the development of Custom Report Items. 

I neglected to credit Chris Hays, whose PolygonCRI Sample stands behind both Teo’s Custom Report Item code and mine. I am happy to say that updates to the SQL Server sample set and the on-line documentation have given Chris’ code the pride of place that it deserves.

In my downloaded copy of the samples, PolygonsCustomReportItem shows up in the C:\Program Files\Microsoft SQL Server\90\Samples\Reporting Services\Extension Samples location, although I couldn’t tell you exactly what download I picked to get it.  You’ll probably find the download instructions buried in the Custom Report Item Sample doc topic, which points to this solution. I’m just skimming this topic now because, frankly, the light gets all bendy-like when I try to read certain portions of the docs, and this is one of them.

In each of the three versions, even though we’re each rendering different types of custom content, you’re going to find a remarkably similar custom rendering approach:

  • You render to an image, using pretty standard Graphics methods.
  • You create an object of Microsoft.ReportingServices.ReportRendering.Image type and you copy what you rendered to that image.  This operation is done with MemoryStream in all three versions of the code — I have no idea whether it’s required or whether Teo just did it that way because Chris did, so I did it too <g> .
  • You provide this object of Microsoft.ReportingServices.ReportRendering.Image type to the standard rendering process as the item-to-be-rendered, when the engine requests it.
My point, and I do have many of them
(said the little polygon)…

I’m writing about this because in the past week I have answered a question about “rich text formatting” in Reporting Services a bunch of times.  Say you have some content stored in a database with RTF markup or HTML markup.  Right now, if you want to use the out-of-the-box RS output rather than writing something to render the whole report yourself, your best option is to create a Custom Report Item. Your code can reads your markup in the data, along with other attributes of the control (such as size and font) and then render the content to an image, however you think it should appear. 

Not a wonderful option, considering that it won’t be searchable text, but do-able. In each answer, for what it’s worth, I’ve also pointed folks to a post on the Katmai RS forum  — which indicates that happier days may be ahead for those of you in this predicament.  You’ll also find that your charting options will improve in Katmai.  Charts have been another big reason to use Custom Report Items in RS.

Still, sometimes nothing beats the low-level approach, and it will be worth your while to understand how to custom-render when the occasion arises, even in Katmai and beyond.

If you’re reading this and scratching your head about how these little gimmicky Custom Report Items connect with your data, realize that you’ve got access to the CustomReportItem’s CustomProperties collection at the time you’re doing this. (The CustomReportItem’s CustomProperties collection is a bit different from the CustomProperties collections of other report elements — and oh how I wish this were not the case — but that’s another post.) 

Take a look at one of Teo’s sample reports.  You will easily see that custom properties can be data bound — I’ll put a truncated version of the XML definition of the ProgressTracker custom item here: 

                    <CustomReportItem Name=”progressTracker1″>
                     <Type>ProgressTracker</Type>
                    <Style>
                         <!– style attributes here –>
                     </Style>
                      <CustomProperties>
                       <CustomProperty>
                          <Name>Value</Name>
                          <Value>=Fields!Product_Gross_Profit_Margin_Status_.Value</Value>
                        </CustomProperty>
                       <CustomProperty>
                         <Name>OutlineColor</Name>
                          <Value>Gray</Value>
                        </CustomProperty>
                      <!– more custom properties here –>
                     </CustomProperties>
                   </CustomReportItem>

How far does this capability go?  As far as you need it to. Looking at Chris’s custom report item’s attributes, PolygonsCRI has a pretty cozy relationship with a dataset:

<CustomProperties>
<CustomProperty>
   <Name>poly:MaxX</Name>
   <Value>=Max(Fields!X.Value,”DataSet2″)+
               iif(Min(Fields!X.Value,”DataSet2″)>0, Min(Fields!X.Value,”DataSet2″),0)
 
</Value>
</CustomProperty>
<CustomProperty>
   <Name>poly:MinX</Name>
   <Value>=iif(Min(Fields!X.Value,”DataSet2″)>0,0,
               Min(Fields!X.Value,”DataSet2″))
 
</Value>
</CustomProperty>
   <!– and so on, lots more here –>
</CustomProperties>

If you look at one of RDLDocumenterDesigner‘s sets of attributes, on the other hand, you will see nothing of the sort. My little custom report item doesn’t bind to data at all, because it has a completely different raison d’être. While it knows how to render itself at runtime, it’s a design-time utility at heart. Just goes to show what a versatile puppy the Custom Report Item really is.