Demystifying DevExpress XtraReport for Silverlight - Part 2

<< part 1 part 3 >>


There are 3 steps involved here.

  • One create/design the reports
  • Two Create the Report Service
  • Three consume the report from the Silverlight Application
  • From the report layout - one can deduce that at least two levels of master-detail will be needed. The first Master-Detail is the customer information with the Total YTD figures. The Detail to that is the Monthly Figures for the given Customer. That now serves as a master to yet another detail which will be the actual details of purchases by the customer for the given month.

    I am assuming you have Visual Studio as well as the necessary DevExpress for Silverlight products installed with the XtraReport as an offering. I am also assuming you have a Client-Server Silverlight Solution. So, having said that, we'll go to the meat of the design. In the server side project or web project, create a sub folder - it is not required but I like to compartmentalize similar things - called Reports.

    From the Reports Folder, right click and add a new item. A dialog similar or close to this - should popup that allows you to select a DevExpress XtraReport class - called - DXperience VXX Report Class. Save that as your base report.


    It is good practice to subclass the standard DevExpress XtraReport offering so as to customize things and do any in-house cleaning necessary.

    The screen picture shows how the report looks like in the designer and what controls are available in the ToolBox.


    You can use any of the controls available in the toolbox under the DevExpress Report control section. The way to display data is through data binding. Most of the controls have DataBinding settings that you can use to bind to columns in a datasource. The designer allows for design time data binding if you can configure the bindingsource control to point to a data repository. There are situations where you can only get the schema information of your dataset at runtime. For these kind of situation, you can still design your report and then at run time bind the controls to the appropriate columns. The designer does not allow for databinding if you do not have a valid datasource at design time

    If you can not specify your datasource at design time, then, you will need to implement the DataSourceDemanded event handler of the report at run time to specify your datasource. What yo will want to do as well in this event handler is specify the bindings of your controls against the report's datasource and then link up the report's datasource to an appropriate dataset or collection.

    The next task is implementing the Details in a Master Detail Relationship. The default report has a couple of bands - Page,Header, Detail,Group,and footer. Most of the bands are self explanatory. For a report bound to a dataset, the Details Band is expected to print for each row or item returned by the dataset or collection. There are basically two ways of doing this - either use the subreport control or use the DetailReportBand. The second approach supposedly offers more than the first but if you are not careful, you could end up with too much implementation and not a lot of separation. I prefer the first approach.

    To use the subreport control - you are basically creating a container for a report class to reside in within the detail band of a Master Report. So, for every row of the Master Dataset printed, a report for the details is also run. The subreport itself can act as a Master for another detail report. The real challenge is how to bind the subreport.

    If you implement the event handler for DATASOURCEDEMANDED event in the subreport - you may be getting funky results. The best place to implement the binding for the subreport is in the BEFOREPRINT event for the subreport control. Here, the details of the Master Row are available at run time and you can use the value to filter the subreport's dataset.

    Another thing I found useful was propagating all the PARAMETERS for the master report to the details report. You can do this in the event handler for the BEFORE PRINT of the subreport. You can also pass in any of the columns values of the current row being processed as a parameter to the report as well.

    For ease of maintenance - you may want to create a subclass for the subreports that you can inherit from and have common functions reside in the ancestor. You can do this by first creating the subclass for the report and then creating the subreports using the type - DevExpress vxx inherited Report Class. After specifying the name and clicking "Add", you will be prompted to specify the report to inherit from. One thing about the inheritance stuff is that - each time you modify the ancestor, you will need to open all the descendants and rebuild all to get the changes propagated properly.

    Finally, one thing that took me a while to figure out. The width of your subreport report class must fit within the width of the details band of the master, if not, you'll end up with lots of blank pages at run time and you'll be pulling your hairs as to why.


    << part 1 part 3 >>

    Comments

    Popular posts from this blog

    Decompiling Delphi - 3

    Decompiling Delphi - 2

    Artificial Intelligence, Oxymoron and Natural Intelligence