Search code examples
winformsreportviewerrdlc

How can I reuse one ReportViewer control for many reports with EF data sources?


I would like to stick with one single form and ReportViewer control, and at runtime assign various reports and data sources. The diverse and complex solutions to this revealed by a quick google check prompted me to rather ask here. How can I achieve this?


Solution

  • You'll need a form featuring a ReportViewer control, RDLC reports, and data sources; there are possibly several ways of implementing this, but you can have a "report manager" class exposing methods that each display a specific report (ex. ShowOrdersReport(), ShowTimeSheetReport(), etc.) - or you could define a base ReportBase class with a Show() method implementation that prompts for parameters when needed... whatever works, it will essentially boil down to this:

    var reportForm = new ReportViewerForm(); // instantiate the form
    // load the report definition into the viewer:
    reportForm.reportViewer1.LocalReport.ReportEmbeddedResource = "Namespace.Report.rdlc";
    
    // loading the data works great with a DataSet:
    var data = _reportingDataSet.Tables[0];
    // create the ReportDataSource with the report data:
    var reportDataSource = new ReportDataSource("rdsReportDataSource", data);
    
    reportForm.ShowReport(new[] { reportDataSource });
    

    Here you'll want to inject the _reportingDataSet dependency; if you're using parameterized stored procedures, you'll want to prompt for the report parameters before you populate the DataSet.

    The ShowReport() method adds the data sources to LocalReport.DataSources, and then calls RefreshReport() which displays the report you've specified.

    public void ShowReport(IEnumerable<ReportDataSource> dataSources)
    {
        foreach (var dataSource in dataSources) 
            reportViewer1.LocalReport.DataSources.Add(dataSource);
    
        reportViewer1.RefreshReport();
    }