DOWNLOAD THE CODE:
Download the Code 93554.zip

How to Render the Subreport
There are two important parts to handling subreports with the ReportViewer control.The first part deals with the way the ReportViewer control finds the definition of any subreports referenced by the main report. Essentially, the ReportViewer control loads the subreport definitions using the same method used to load the main report. When the ReportViewer control reads the report definition from the file system based on a path specified in the ReportPath parameter, the control will read the subreport definitions from the file system as well. (When the report definition is loaded using the LoadReportDefinition method, you must use the LoadSubreportDefinition method to load the report definitions for any subreports.)

When the ReportPath parameter is used, the ReportViewer control looks for the subreports in the same folder in which it found the main report.The ReportViewer control uses the name of the subreport specified in main report definition as the name of the subreport definition file. It assumes a file extension of .rdlc. Even if you specify that the main report file has an .rdl extension, the ReportViewer control will still use an .rdlc extension for the subreport. So, to make the subreport code work properly, you must rename the subreport definition file from EmployeeAssignments.rdl to EmployeeAssignments.rdlc.

The second part of handling subreports deals with creating the data sets for the subreport. Each time a subreport is rendered, you must use the local report's Subreport-Processing event to supply code that creates the necessary data sets for that subreport. When a subreport is rendered, this event fires. It's up to you to handle this event properly, which brings us to the code between callout A and callout B in Listing 2.This code assigns a subroutine to serve as the event handler for the SubreportProcessing event. In this case, the subroutine is named GalacticSubreportProcessingEvent-Handler.

GalacticSubreportProcessingEventHandler first gets the value for the Employee-Number parameter passed from the main report to the subreport. The subroutine then uses the EmployeeNumber parameter's value to create a result set and adds that result set to the collection of data sources used by the subreport. As with the main report, the name of the data set must match the name in the subreport's definition.

With the necessary code in place, the application is now ready to render both the report and subreport. When a user selects entries in the checked list box and clicks the Render Report button, the user will get results similar to those in Figure 2.

Rendering Behind the Scenes
In addition to being added as a visual control on a form, the ReportViewer control can function as an object instantiated in code without a visual presence. When used in this manner, you can use the Report-Viewer control to render reports in any of the supported rendering formats, including spreadsheet (.xls), PDF, and XML. You can then use these rendered reports within the application or write them to a file. You can also render reports in Enhanced Meta-File (EMF) format and send them directly to a printer. You can even render the report as an image and use that image as the background to a control or form.

Listing 3 shows the code that makes our sample report a background image in a form. As callout A in Listing 3 shows, the code uses a subroutine to create an instance of the ReportViewer control, point the viewer at the report definition, and supply the required data set. Although this code is similar to that used in Listing 1 and Listing 2, the rest of the code in the subroutine differs from what you've seen so far. As callout B in Listing 3 shows, the subroutine defines an XML structure named deviceInfo. This structure provides information (e.g., page size, margin size) required by the various rendering formats. Next, the code prepares for the Render method, which will place the rendered report's pages in a list of streams (one stream for each page). The preparations include initializing the list of streams to an empty list and providing a callback function that will create a new stream for each new page.The callback function, which is named CreateStream, appears at the end of Listing 3.

With the necessary preparations made, the subroutine finally calls the Render method.The method's first parameter specifies the rendering format. As callout C in Listing 3 shows, the format in this example is Image. After the method is called, you can use the streams as desired. In this case, the first and only stream is the first page of the Employee List report, which is converted to a bitmap and assigned to the form's BackgroundImage property. Figure 3 shows the result.

Reports Anywhere and Everywhere
The ReportViewer control is an extremely flexible tool. It supplies you with a convenient way to display reports residing on a Reporting Services report server. It also provides the means for you to render reports in a completely self-contained environment, severing your ties to the report server. To borrow an old advertising slogan, with the ReportViewer control, Reporting Services reports can truly be everywhere you and your users want to be.

End of Article

Prev. page     1 [2]     next page -->



You must log on before posting a comment.

If you don't have a username & password, please register now.

 
 

ADS BY GOOGLE