Report Viewer in WPF


In the following article I am going to share my experience of using ReportViewer Control with WPF.

First of all let's have a small discussion on ReportViewer Control.

ReportViewer

ReportViewer is a freely redistributable control that enables embedding reports in applications developed using the .NET Framework. We can easily design the reports with drag-n-drop simply using Report Designer included in Visual Studio 2010.

The benefits that are offered by ReportViewer Control:

  1. The reporting engine built into ReportViewer can perform operations such as filtering, sorting, grouping and aggregation. And hence processes data efficiently
  2. To present data it supports a variety of ways. So that the data can be present as lists, tables, charts and matrices (also known as crosstabs.)
  3. It adds visual appeal. This means we can specify fonts, colors, border styles, background images etc. to make our report visually appealing.
  4. Enables interactivity in reports. We can have collapsible sections, document map, bookmarks, interactive sorting etc. in our report.
  5. Conditional formatting is also supported by report viewer. We can embed expressions in the report to change display style dynamically based on data values.
  6. Supports printing and print preview.
  7. Supports export to Excel, Word and PDF formats.

Generally we follow the usage of the Report Viewer in Windows Form programs. But here we are going to use this in WPF application.

Step by step creation of report using ReportViewer Control in WPF application

1. Very first step is to open a new project of WPF Application project type and name it to "ReportViewerWPF".

RptWPF1.jpg

2. Secondly, click on the Toolbox, and drag a "WindowsFormsHost" control onto the design surface for MainWindow.xaml. This also adds the assemblies that are needed by WindowsFormstHost to our project.

RptWPF2.jpg

Code

<WindowsFormsHost Height="100" Width="100" Name="windowsFormsHost1"/>

3. Now, in Solution Explorer, right-click on the project and select Add Reference.

RptWPF3.jpg

4. In the .NET tab of the Add Reference dialog log, select the Microsoft.ReportViewer.WinForms assembly, and click OK. After adding successfully it shows in the solution explorer pane under the head "Refrences".

RptWPF4.jpg

RptWPF5.jpg

5. Also add the highlighted lines to your code:

   <Window x:Class="ReportViewerWPF.MainWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:rv="clr-namespace:Microsoft.Reporting.WinForms;
             assembly=Microsoft.ReportViewer.WinForms"
   Title="MainWindow" Height="300" Width
="400">
     <Grid>
        <WindowsFormsHost Name="windowsFormsHost1">
            <rv:ReportViewer x:Name="_reportViewer"/>
        </WindowsFormsHost>
     </Grid>
   </
Window>

This creates an instance of ReportViewer named _reportViewer in the XAML page.

6. Now let's create an RDLC report that you will display in the ReportViewer control. And for this, In Solution Explorer, right-click your project, point to Add, and select New Item.

RptWPF6.jpg

7. In the Add New Item dialog box, select Report Wizard which is in Reporting template, and click Add. This will open the Report Wizard with the Data Source Configuration Wizard like this:

RptWPF7.jpg

RptWPF8.jpg

8. In the Data Source Configuration Wizard, select your Database and click Next, then again select Dataset, and click Next.

RptWPF9.jpg

RptWPF10.jpg

9. After clicking on Next, Choose Your Data Connection page will be open, click New Connection. If you see the Choose Data Source dialog box, select Microsoft SQL Server and click Continue.

RptWPF11.jpg

10. In the Server name box, type the server name that hosts your database that you are going to select, as I have used the localhost and for this I have to log on to my server and in "Select or enter a database" name, select the database which you are going to use, and test your connection before clicking OK.

RptWPF12.jpg

11. Click Next button twice, so that the page "Choose your Database Objects" will be opened .

12. In the Choose Your Database Objects page, expand the Tables node, select the checkbox for the table for which you want to create a report, and click Finish.

RptWPF13.jpg

13. A DataSet object called YourDatabaseNameDataSet is now created in your project.

RptWPF14.jpg

14. In the Report Wizard, click Next.

15. In the Arrange Fields page, drag all the available fields and drop to the Values pane. This creates a simple tabular table for displaying the sample data. Then, click Next two times and lastly click on Finish to close the Report Wizard.

RptWPF15.jpg

16. Now your window of report.rdlc will look like as under:

RptWPF16.jpg

17. Next, it's time to add the code to point ReportViewer to the new report that we have created and also to add data from "YourDatabaseNameDataSet" to ReportViewer.
18. Open MainWindow.xaml.cs, and add the following lines:

MainWindow.xaml.cs:

namespace ReportViewerWPF

    public partial class MainWindow : Window
    {
       public MainWindow()
        {
            InitializeComponent();
            _reportViewer.Load += ReportViewer_Load;
        }
        private bool _isReportViewerLoaded;

        private void ReportViewer_Load(object sender, EventArgs e)
        {
            if (!_isReportViewerLoaded)
            {
                Microsoft.Reporting.WinForms.ReportDataSource reportDataSource1 = new      
                Microsoft.Reporting.WinForms.ReportDataSource();
                WpfApplication4DataSet dataset = new WpfApplication4DataSet();

                dataset.BeginInit();

                reportDataSource1.Name = "DataSet1";
               
//Name of the report dataset in our .RDLC file

                reportDataSource1.Value = dataset.Accounts;
                this._reportViewer.LocalReport.DataSources.Add(reportDataSource1);

                this._reportViewer.LocalReport.ReportPath = "../../Report.rdlc";                    
                dataset.EndInit();

                //fill data into WpfApplication4DataSet
                WpfApplication4DataSetTableAdapters.AccountsTableAdapter
                accountsTableAdapter = new   
                WpfApplication4DataSetTableAdapters.AccountsTableAdapter();
 
                accountsTableAdapter.ClearBeforeFill = true;
                accountsTableAdapter.Fill(dataset.Accounts);                    
                _reportViewer.RefreshReport();
                _isReportViewerLoaded = true;
            }
        }
    }
}