Working with Report Viewer, RDLC files and Sub reports

First of all I would like to say, what a big headache this was in figuring out this thing.  >If you create two separate reports and one needs to be the sub report of the other, you will need to do a few things to get it to work.  Let’s assume that you have already created the two blank reports contact_report.rdlc and phoneno_report.rdlc  where the contact_report.rdlc will show the details of the phoneno_report.rdlc linked by a single primary key (index key) value ContactID.

Ill assume that you have the dataset ready with the two tables that you will be using as the contact details and phone no data sources.  We will start working with the phoneno_report.rdlc. Select the type of control you will be using to display the data in from the toolbox.

I will use the table control. Now drag that control to the  phoneno_report that you have created. Now open up your data source window and drag the fields that you wish to display on the report.

After dragging the fields from your data sources tree view it should look like this.

No we have to create the linking field or parameter ContactID so the parent report can pass this data to the child report. Right click on an open area of the report and bring up the report parameter options.

Next create the parameter ContactID and I just fill in the prompt as ContactID and change the data type to integer.

Now we can work on the filtering. Highlight the table that the data will be displayed and right click on it and select properties. On the properties window, select the filter tab and create the filter expression in the filter list area. It should be datasouce.ConactID == Parameter.ContactID.

When you have done that then there is one thing left to do. Make sure that there is only ONE data set assigned to this report. To do this, head to the top menu of visual studios and under the report menu item, select the report data source.

Make a note of that data source name because you’re going to need it when populating the report with records.

Now lets design our main contacts report.  We will drag our control to the report in which we want to display the records. I will use the list control this time.

After you have finished dragging the fields you wish to display from the data source window and making it all pretty, go and double check to make sure the only one data source associated with this report. Make a note of that data set name.

Now everything is ready for us to add the sub report phone no report.  On the toolbox window go ahead and drag the sub report control onto your report.

I will look like this on your main report. Make sure you name it as well.

Now highlight the sub report control and right click on it to bring up the properties window.

On the properties window select the parameters tab and enter the parameter details.

Finally you have finished with the report designs. Now it’s time to do some coding to fill those data sets you made a note of.

Add a report viewer control to your form. Make sure it’s for rdlc and not crystal reports. Double click on the form and bring up the code. You will need to include these using directives.

using System.Windows.Forms;

using Microsoft.Reporting.WinForms;

Now we need to fill those report data sources with data.

To fill the parent report data source  we need to use the ReportDataSource object.

I hope you made a note of those data set names, you will need to recall them now.

ReportDataSource datasource = new ReportDataSource("Query_selectContact", this.<mycooldatafetcher>.SelectAll());

reportviewerRpt.LocalReport.DataSources.Clear();

//set the report location of the contact_report.rdlc

reportviewer1.LocalReport.ReportPath = reportPath();

//add the datasource to the report contact_report.rdlc

reportviewer1.LocalReport.DataSources.Add(datasource);

reportviewer1.LocalReport.Refresh();

reportviewer1.RefreshReport();

 

Now this is a crucial part of loading the sub reports with the data you want to display. You need to utilize the SubreportProcessing event handler.

reportviewer1.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(ItemsSubreportProcessingEventHandler);

protected void ItemsSubreportProcessingEventHandler(object sender,

SubreportProcessingEventArgs e)

        {

switch (e.ReportPath)

            {

                case "contactsPhone"://  I hope you remembered to name your report.

  String ContactID = e.Parameters[0].Values[0];// Get the ContactID from the parameter you  created.

 

                    DataSet  dsPhone = new DataSet();

                    dsPhone.Tables.Add(<mycooldatafetcher>.SelectPhoneAttributeByContactID(

Convert.ToInt32(ContactID)));

 

//I hope you remembered the name of the data source from the sub report you created

ReportDataSource datasourcePhoneNo = new ReportDataSource("Query_selectPhoneAttribute", dsPhone.Tables[0]);                  

 e.DataSources.Clear();

                    e.DataSources.Add(datasourcePhoneNo);

                    break;

                default:

                    break;

            }

}

There you go, I hope this helps someone going through the same frustration I went through trying to figure this out. If this was helpful, leave a comment.