A Problem when Dynamically Switch .rdlc in ReportViewer

2011-06-20


Normally in a Windows Form project, you have multiple .rdlc template files. You can use a single ReportViewer control to dynamically bind the report file to multiple .rdlc files dynamically.

Please look at the following sample:

...
ReportParameter rp;
this.reportViewer1.LocalReport.DataSources.Clear();
try
{
    switch (reportType)
    {
        #region Analog Day Report
        case ReportType.AnalogDay:
            start_time = dtpDateStart.Value;
            AnalogReportObjList analogDailyRepObjList = new AnalogReportObjList();
            this.reportViewer1.LocalReport.ReportPath = this.baseRDLCFolder + "ReportAnalogDay.rdlc";
            rp = new ReportParameter("CompanyName", this.tbCompany.Text.Trim(), false);
            ReportParameter rpSelectedDate = new ReportParameter("SelectedDate", this.dtpDateStart.Value.ToString("yyyy-MMM-dd"));
            this.reportViewer1.LocalReport.SetParameters(new ReportParameter[] { rp, rpSelectedDate }); 
            this.reportViewer1.LocalReport.DataSources.Add(
                new ReportDataSource("DataSet1", analogDailyRepObjList.GetAnalogDailyReportObjList(start_time, this.ListHostDBIndexSelected)));
            // Process and render the report
            this.reportViewer1.RefreshReport();
            break;
        #endregion
        
        #region Analog Shift Report
        case ReportType.AnalogShift:
            start_time = dtpDateStart.Value;
            AnalogReportObjList analogShiftRepObjList = new AnalogReportObjList();
            this.reportViewer1.LocalReport.ReportPath = this.baseRDLCFolder + "ReportAnalogShift.rdlc";
            rp = new ReportParameter("CompanyName", this.tbCompany.Text.Trim());
            ReportParameter rpShift = new ReportParameter("ShiftName", ((ListItem)this.cbShift.SelectedItem).Value.Trim());
            ReportParameter rpShiftTime = new ReportParameter("ShiftTime", this.dtpDateStart.Value.ToString("yyyy-MMM-dd HH:mm:ss"));
            this.reportViewer1.LocalReport.SetParameters(new ReportParameter[] { rp, rpShift, rpShiftTime });  
            this.reportViewer1.LocalReport.DataSources.Add(
                new ReportDataSource("DataSet1", analogShiftRepObjList.GetAnalogByShiftReportObjList(
                    Convert.ToInt32(((ListItem)this.cbShift.SelectedItem).Value.Trim()),
                    start_time, 
                    this.ListHostDBIndexSelected)));
            // Process and render the report
            this.reportViewer1.RefreshReport();
            break;
        #endregion
        
        ...
    }
}
...

However, when you run above code, you will get the following error message:

"an error occurred during local report processing"

When you read detail information or debug, you will find another related error message:

"An attempt was made to set a report parameter 'xxxxx' that is not defined in this report" (xxxx is a Parameter name which you set in your .rdlc file)

No matter we tried to add "this.reportViewer1.LocalReport.DataSources.Clear();" in each case beginning , or load the Refresh() for reportViewer, or adjust code’s order, we still met the same error message.

There are not enough similar sample on internet, so we had to try to find reason ourselves. Finally, we found it is simple to resolve the issue.

We need to reset report viewer when start each case. add one line of code, then everything will be OK:

...
ReportParameter rp;

this.reportViewer1.Reset(); 

this.reportViewer1.LocalReport.DataSources.Clear();
try
{
    switch (reportType)
    {
      case ...
             ...
    }
    ...
}