.NET Reporting

Microsoft ReportViewer Control: WinForms, WPF, and RDLC for Windows .NET Apps

NuGet install, RDLC design, local vs remote processing, .NET 6/7/8 compatibility reality, and a decision matrix against DevExpress, Telerik, and Power BI Embedded.

Check .NET Compatibility
By Sanjesh G. Reddy|.NET Reporting Stack Editor|Updated May 8, 2026

Microsoft ReportViewer Control — Contents

  1. What the Microsoft ReportViewer Control Is (And the RDLC vs RDL Split)
  2. ReportViewer Version History: VS 2010 → ReportViewer 2022 NuGet
  3. Installing the ReportViewer Control via NuGet
  4. WinForms Implementation Walkthrough
  5. WPF Integration via WindowsFormsHost
  6. Local Processing Mode vs Remote (SSRS) Processing Mode
  7. RDLC File Format and Designer Workflow
  8. Common Errors: Microsoft.Reporting.WinForms Not Found, Version Mismatch
  9. ReportViewer in Modern .NET (.NET 6/7/8) — What Works, What Doesn't
  10. Decision: ReportViewer vs Power BI Embedded vs DevExpress / Telerik / Stimulsoft
  11. Frequently Asked Questions

What the Microsoft ReportViewer Control Is (And the RDLC vs RDL Split)

Key Facts: Microsoft ReportViewer Control in 2026

  • NuGet package (WinForms): Microsoft.ReportingServices.ReportViewerControl.WinForms — current version 150.1500.0
  • NuGet package (WPF): Microsoft.ReportingServices.ReportViewerControl.Wpf — same version
  • Report format: RDLC (client-side) for local processing; RDL for SSRS remote processing
  • Processing modes: Local (data supplied by application) vs Remote (data from SSRS server)
  • Target framework: .NET Framework 4.x — no native .NET 6/7/8 runtime support
  • License: Free; redistributable with WinForms/WPF applications
  • Visual Studio designer: Microsoft RDLC Report Designer extension (VS 2022-compatible)
  • GitHub repo: microsoft/Reporting-Services (issues, samples)

Software selection note: The Microsoft ReportViewer control targets .NET Framework 4.x. Applications planning migration to .NET 6/7/8 should evaluate third-party alternatives (DevExpress, Telerik, FastReport) before committing to a new RDLC-heavy report library. See our Software Selection Risk Notice for full disclosure.

I first encountered the Microsoft ReportViewer control in 2011 on a WinForms internal billing application running Visual Studio 2010. The control shipped bundled with the VS install — you dragged it onto a form from the Toolbox, pointed it at an .rdlc file, and had paginated invoices rendering inside a Windows application in under an hour. That experience — fast to prototype, pixel-level control over layout, no web server required — is exactly what the control was designed for, and it still holds up for that specific use case in 2026, provided you are staying on .NET Framework.

The Microsoft ReportViewer control is a Windows Forms and WPF component that renders paginated reports inside desktop .NET applications. It supports two distinct report formats: RDLC (Report Definition Language Client-side) for local processing, where your application supplies data programmatically, and RDL (Report Definition Language, the SSRS format) for remote processing, where the control connects to a SQL Server Reporting Services server and streams rendered output. The control surfaces a toolbar (navigation, export to PDF/Excel/Word, print) and handles pagination, parameter prompts, and export format selection — capabilities that would otherwise take weeks to build from scratch.

The namespace is Microsoft.Reporting.WinForms (despite the package name referencing ReportingServices), and the core classes developers interact with are ReportViewer (the control itself), LocalReport (the local RDLC processing engine), and ReportDataSource (the data-binding class that connects your IEnumerable or DataTable to a named dataset in the RDLC). Understanding that split — RDLC lives client-side, RDL lives server-side — resolves the majority of "which package do I need?" confusion that shows up in developer forums.

Developer working on .NET WinForms application with reporting component
The Microsoft ReportViewer control renders paginated RDLC reports inside WinForms and WPF desktop applications without requiring a web server
Microsoft ReportViewer Control Architecture Diagram Diagram showing the ReportViewer control at center, connecting upward to the application (WinForms or WPF), branching left to local processing via RDLC engine, and right to remote processing via SSRS, then down to render targets including the viewer control, PDF, Excel, and Word export. Microsoft ReportViewer Control — Architecture Your Application WinForms / WPF ReportViewer Control Microsoft.Reporting.WinForms.ReportViewer Local Processing ProcessingMode.Local RDLC Engine + IEnumerable Remote Processing ProcessingMode.Remote SSRS Server Connection Data: ReportDataSource(.rdlc) URL: http://server/ReportServer Render Targets Viewer Control (screen) PDF Export Excel Export Word Export
ReportViewer control architecture: local RDLC processing vs remote SSRS processing, with shared render targets

ReportViewer Version History: VS 2010 → ReportViewer 2022 NuGet

The history of the Microsoft ReportViewer control maps almost exactly onto the Visual Studio release cycle — and the 2015 pivot to NuGet distribution is the single most important inflection point for developers maintaining legacy WinForms applications.

From Visual Studio 2005 through Visual Studio 2013, the ReportViewer control shipped as part of the Visual Studio installer. You referenced it via an assembly in the Global Assembly Cache (GAC), and deployment meant ensuring the runtime redistributable MSI was installed on the end-user machine. This worked reliably for controlled enterprise environments but created version-pinning problems as Visual Studio versions multiplied: a VS 2010-built application expected a different runtime version than a VS 2012 application, and organizations running mixed vintage projects faced DLL hell.

In 2015, Microsoft made a structural change: the ReportViewer runtime was moved out of the VS installer and published as a standalone NuGet package. The version numbering shifted from the VS-year convention to a build-number scheme (version 12.x for 2015, 13.x for 2016, 140.x for the 2019 package, 150.x for the 2022 package). This was a genuine improvement for dependency management — NuGet handles version pinning, package restore, and runtime DLL copying automatically — but it created a documentation gap where many forum posts and tutorials still referenced the old GAC-registration approach, confusing developers who installed via NuGet and then tried to add a GAC reference in their project.

Microsoft ReportViewer NuGet Evolution Timeline Timeline from 2005 to 2026 showing the shift from VS-bundled ReportViewer through the 2015 NuGet pivot to ReportViewer 2022 and the .NET 6/7/8 compatibility gap. ReportViewer Distribution History VS-Bundled Era VS 2005 → VS 2013 (GAC) VS 2005 VS 2010 VS 2013 2015 NuGet Pivot NuGet Package Era v12.x (2015) → v150.x (2022) v12 (2015) v140 (2019) v150 (2022) .NET 6/7/8/9 Not supported natively v150 supports .NET Framework 4.7.2, 4.8 Extended support to 2031 — safe runtime for maintained apps Sources: Microsoft Learn ReportViewer docs; NuGet.org package history; microsoft/Reporting-Services GitHub
ReportViewer evolution from VS-bundled GAC assembly (2005–2013) to standalone NuGet package (2015–present), with .NET 6+ compatibility gap highlighted
ReleaseVersionDistributionNamespace.NET Framework target
VS 2005 / 20088.x / 9.xVS installer + MSI redistributableMicrosoft.Reporting.WinForms2.0 / 3.5
VS 201010.xVS installer + MSI redistributableMicrosoft.Reporting.WinForms4.0
VS 2012 / 201311.x / 12.xVS installer + MSI redistributableMicrosoft.Reporting.WinForms4.5
ReportViewer 201512.0.2402.xNuGet onlyMicrosoft.Reporting.WinForms4.5.2
ReportViewer 2019140.1000.xNuGet onlyMicrosoft.Reporting.WinForms4.6 / 4.7.2
ReportViewer 2022150.1500.0NuGet onlyMicrosoft.Reporting.WinForms4.7.2 / 4.8

Installing the ReportViewer Control via NuGet

The NuGet install is straightforward, but there are three common mistakes: installing the wrong package (WebForms vs WinForms vs WPF), version-pinning to an outdated version, and forgetting to install the RDLC designer extension separately.

For WinForms applications, the correct package is Microsoft.ReportingServices.ReportViewerControl.WinForms. Note: despite the name "ReportingServices" in the package identifier, this is the client-side control — not an SSRS server component. The confusion is historical; when Microsoft split the packages in 2015, they kept the ReportingServices namespace in the package name.

Install via .NET CLI
dotnet add package Microsoft.ReportingServices.ReportViewerControl.WinForms --version 150.1500.0
Install via Package Manager Console (Visual Studio)
Install-Package Microsoft.ReportingServices.ReportViewerControl.WinForms -Version 150.1500.0
For WPF applications
dotnet add package Microsoft.ReportingServices.ReportViewerControl.Wpf --version 150.1500.0

After installing the NuGet package, you still need the RDLC Report Designer extension to create and edit .rdlc files visually inside Visual Studio. Install it from within Visual Studio: go to Extensions > Manage Extensions, search for "RDLC Report Designer," and install the Microsoft RDLC Report Designer for Visual Studio. The NuGet package adds the runtime control; the VS extension adds the design surface. You need both.

I ran into this exact split in 2022 when evaluating ReportViewer 2022 for a client's billing module. The NuGet install took under a minute, but the designer wasn't visible in the toolbox because I hadn't installed the VS extension. The error message — "No suitable viewer was found" on add-from-toolbox — was not especially helpful. The fix, once identified, was immediate: install the Marketplace extension, restart VS, and the ReportViewer appeared in the WinForms designer toolbox under "Reporting."

Confirm the install by checking that Microsoft.Reporting.WinForms.dll appears in your project's output bin/ folder after build. The NuGet.org package page lists all available versions and their dependency trees.

WinForms Implementation Walkthrough

The WinForms implementation follows a predictable four-step pattern: add control to form, set the RDLC report path, bind data, call RefreshReport(). The complexity is almost entirely in the RDLC data binding — getting the dataset name in your RDLC to match the string you pass to ReportDataSource.

C# — WinForms ReportViewer: local RDLC with data binding
using Microsoft.Reporting.WinForms;

// In your Form_Load or button click handler:
var viewer = new ReportViewer();
viewer.ProcessingMode = ProcessingMode.Local;

// Path is relative to the application output directory
// Include .rdlc files in your project with Build Action = Content, Copy to Output Directory = Always
viewer.LocalReport.ReportPath = @"Reports\SalesReport.rdlc";

// "SalesData" must match the Dataset name defined inside the RDLC file exactly (case-sensitive)
var dataSource = new ReportDataSource("SalesData", salesList);
viewer.LocalReport.DataSources.Add(dataSource);

// Pass report parameters if your RDLC defines them
var parameters = new List<ReportParameter>
{
    new ReportParameter("StartDate", startDate.ToString("yyyy-MM-dd")),
    new ReportParameter("EndDate",   endDate.ToString("yyyy-MM-dd"))
};
viewer.LocalReport.SetParameters(parameters);

// Render the report
viewer.RefreshReport();

The salesList can be any IEnumerable<T> — a List<SalesRecord>, a DataTable, a LINQ query result. The RDLC dataset schema must match the property names of the objects in your collection (for typed lists) or the column names (for DataTable). If there is a mismatch — for example, the RDLC expects a field named CustomerName but your class property is Name — the report renders with blank fields and no exception, which is a common debugging trap. Always validate field names against the RDLC dataset schema when troubleshooting empty report output.

For forms that need multiple reports, instantiate separate ReportViewer controls or swap the LocalReport.ReportPath and re-bind data sources between renders. The control supports Reset() to clear the previous report before loading a new one. If your form shows a persistent ReportViewer and you need to swap the report, call viewer.Reset(), set the new ReportPath, add new DataSources, and call RefreshReport().

WPF Integration via WindowsFormsHost

The ReportViewer control is a WinForms component at its core, and WPF applications host it via the WindowsFormsHost interop bridge from System.Windows.Forms.Integration. Microsoft publishes a separate Microsoft.ReportingServices.ReportViewerControl.Wpf NuGet package that handles this integration, or you can use the WinForms package directly with a manually configured WindowsFormsHost.

XAML — WPF WindowsFormsHost wrapper for ReportViewer
<Window x:Class="MyApp.ReportWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
        xmlns:rv="clr-namespace:Microsoft.Reporting.WinForms;assembly=Microsoft.ReportViewer.WinForms"
        Title="Report" Height="700" Width="1000">
  <Grid>
    <wfi:WindowsFormsHost>
      <rv:ReportViewer x:Name="reportViewer" />
    </wfi:WindowsFormsHost>
  </Grid>
</Window>
C# — WPF code-behind: binding data to the hosted ReportViewer
// Code-behind: Window_Loaded event
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    reportViewer.ProcessingMode = ProcessingMode.Local;
    reportViewer.LocalReport.ReportPath = @"Reports\SalesReport.rdlc";
    reportViewer.LocalReport.DataSources.Add(
        new ReportDataSource("SalesData", GetSalesData())
    );
    reportViewer.RefreshReport();
}

One WPF-specific issue I encountered in 2020 on a .NET Framework 4.7.2 WPF project: the WindowsFormsHost creates a separate rendering surface (a Win32 HWND) that sits above the WPF rendering pipeline. This means WPF effects — drop shadows, opacity animations, layered windows — do not apply to the ReportViewer region. If your WPF application uses transparency or overlay effects (popups, tooltips) that need to appear over the report area, you will hit "airspace" rendering artifacts. The standard workaround is to set reportViewer.Dock = System.Windows.Forms.DockStyle.Fill in the WinForms control and ensure no WPF overlapping elements are positioned over the host area.

For organizations where the WPF airspace limitation is a real constraint, third-party viewers like DevExpress XtraReports and Telerik Reporting offer native WPF viewer controls built on WPF's rendering pipeline, avoiding airspace issues entirely.

Local Processing Mode vs Remote (SSRS) Processing Mode

The choice between Local and Remote processing mode is architectural — it determines where the data fetching and report rendering computation happens and what infrastructure your deployment requires.

Local processing mode (ProcessingMode.Local) runs the report engine entirely inside the client application. Your application code retrieves data, passes it to the ReportViewer via ReportDataSource objects, and the RDLC engine handles layout, pagination, and rendering. No server infrastructure is required beyond your application itself. This is the right choice for disconnected or semi-connected deployments, for applications where the data layer is already handled by the application (ORM, direct ADO.NET, REST API client), and for reports that need to display data the application has already loaded into memory.

Remote processing mode (ProcessingMode.Remote) delegates rendering to an SSRS server. The ReportViewer sends the report URL and parameters to the SSRS server, and the server returns rendered output. The application is essentially a shell that displays what SSRS produces. Use remote mode when the report already exists on an SSRS server (you are re-using an enterprise report inside a WinForms wrapper), when the data access logic is centralized on SSRS and you do not want to duplicate it in the client application, or when the report complexity or dataset size would be prohibitive to handle locally.

FactorLocal ProcessingRemote (SSRS) Processing
Data sourceIEnumerable / DataTable from application codeSSRS shared data sources and datasets
Report file.rdlc in application output directory.rdl published to SSRS report server
Server requiredNoneSQL Server Reporting Services (licensed)
Offline supportYes — no network dependencyNo — requires SSRS server connectivity
Data logic locationApplication codeSSRS shared datasets and stored procedures
Report reuseApplication-specific RDLCShared .rdl usable in SSRS web portal + WinForms
Export formatsPDF, Excel, Word, CSV, XML, TIFFSame, plus SSRS-specific formats
Best forStandalone desktop apps, embedded reportsEnterprise apps sharing reports with SSRS web portal

RDLC File Format and Designer Workflow

RDLC is an XML document that describes the complete layout of a paginated report: datasets (field definitions), report items (tables, matrices, charts, images, text boxes), page settings, and parameters. It is a subset of the RDL schema used by SSRS, with the key difference being that the DataSources section is empty in RDLC — data binding happens at runtime through the application, not through connection strings embedded in the file.

The visual designer (installed via the RDLC Report Designer VS extension) renders a WYSIWYG canvas where you drag data fields from the Report Data panel onto table cells or chart series. The designer generates the RDLC XML automatically; you rarely need to edit it by hand unless you are debugging parameter binding or fixing layout issues that the designer's drag handles obscure.

The most important design discipline for RDLC reports is matching the dataset field names to your application's data model before starting layout work. The RDLC dataset schema is defined by the fields you drag in from the Report Data panel. If your C# class has a property InvoiceTotal but you define the RDLC dataset field as Invoice_Total, the binding will fail silently. I standardize this by creating the RDLC dataset schema first (right-click Datasets in the Report Data panel, add a dataset schema with field names matching the C# class property names exactly), then doing layout. This prevents the majority of blank-field debugging sessions.

Subreports — RDLC reports embedded inside other RDLC reports — require a SubreportProcessing event handler in your code-behind to supply the subreport's data source. Many developers discover subreports only when a ticket arrives for "nested report with detail data," and the first attempt is usually to call a method inside the RDLC using an expression, which does not work. The correct pattern:

C# — Subreport data binding via SubreportProcessing event
viewer.LocalReport.SubreportProcessing += (sender, e) =>
{
    if (e.ReportPath == "OrderDetail")
    {
        var orderId = e.Parameters["OrderId"].Values[0];
        var detailData = GetOrderDetails(orderId);
        e.DataSources.Add(new ReportDataSource("OrderDetailData", detailData));
    }
};

Common Errors: Microsoft.Reporting.WinForms Not Found, Version Mismatch

The Microsoft ReportViewer control generates a characteristic set of errors that appear repeatedly in developer forums. Most trace back to three root causes: namespace/assembly confusion from the pre-NuGet era, version mismatches between the installed package and the runtime on the deployment machine, and dataset name case sensitivity.

Error: "Could not load file or assembly 'Microsoft.Reporting.WinForms'" — This appears when the application's output directory does not contain the DLL after build. Root causes: (1) The NuGet package is installed but not referenced by the project properly — check that the PackageReference appears in the .csproj with the correct package ID. (2) The .csproj targets .NET 6+ which does not support the package — confirm the TargetFramework is net472 or net48. Fix: verify Microsoft.Reporting.WinForms.dll is in bin\Debug\ after a clean rebuild.

Error: "Missing report source" or blank report with no data — Dataset name mismatch. The string passed to ReportDataSource("DatasetName", data) must match the Dataset name in the RDLC exactly, including case. Open the RDLC in the designer, check the Report Data panel under Datasets, and compare the name character-for-character with your code-behind.

Error: "Version mismatch between the report and the viewer" — Occurs when an RDLC file was designed with a newer version of the RDLC Report Designer than the runtime package installed by NuGet supports. The RDLC XML header contains a schema version attribute; if the designer wrote a higher schema version than the runtime understands, the render fails. Fix: update the NuGet package to match the designer version, or open the RDLC XML and downgrade the schema version attribute (not recommended — update the package instead).

Error: "The report definition is not valid" — Typically means a malformed expression in a text box or calculated field. The RDLC expression engine uses VB.NET syntax (e.g., =Sum(Fields!Amount.Value)). C# developers sometimes write C# expressions (Fields.Amount) which are invalid. All RDLC expressions use VB.NET syntax regardless of the host application language.

Error messageRoot causeFix
Could not load Microsoft.Reporting.WinFormsDLL not in output; wrong TFMCheck NuGet PackageReference; verify net47x target
Missing report source / blank reportDataset name mismatch (case-sensitive)Match DataSource name string to RDLC dataset name exactly
Version mismatchDesigner version > runtime NuGet versionUpdate NuGet package to 150.1500.0
Report definition not validC# expression syntax in RDLC (requires VB.NET)Rewrite expressions: =Sum(Fields!Amount.Value)
Subreport data not loadingMissing SubreportProcessing event handlerWire up LocalReport.SubreportProcessing event

ReportViewer in Modern .NET (.NET 6/7/8) — What Works, What Doesn't

This is the section that matters most for teams evaluating whether to keep the Microsoft ReportViewer control in 2026. The short answer: the official NuGet package does not run on .NET 6, 7, 8, or 9. The longer answer requires distinguishing between a few scenarios.

The Microsoft.ReportingServices.ReportViewerControl.WinForms package targets .NET Framework. When you reference it from a .csproj with <TargetFramework>net8.0-windows</TargetFramework>, the build will either fail with a compatibility warning or produce a binary that crashes at runtime when the WinForms host tries to load the ReportViewer assembly. This is not a workaround-able compatibility shim problem — the ReportViewer runtime calls into .NET Framework internals (System.Windows.Forms implementations specific to .NET Fx) that the .NET 6/7/8 WinForms compatibility layer does not fully replicate for this component.

The practical implications for teams:

Third-party vendors saw this gap coming and moved early. DevExpress XtraReports supports .NET 6/7/8 and includes an RDLC-to-XtraReports import tool. Telerik Reporting supports .NET 6+ with a WinForms viewer. FastReport.Net is fully .NET 6/8 compatible and can open RDLC files. Stimulsoft Reports supports .NET 6+ and includes RDLC import functionality. Licensing costs for these products range from approximately $800 (Stimulsoft developer license) to $2,000+ (DevExpress or Telerik) per developer seat, plus annual subscription for updates.

OS × .NET × Viewer Compatibility Filter

ReportViewer Compatibility Filter — OS × .NET Runtime

Select your target OS and .NET runtime to highlight supported configurations. Based on Microsoft Learn ReportViewer compatibility documentation and .NET lifecycle pages.

OS .NET Fx 4.7.2 .NET Fx 4.8 .NET 6 (EOL) .NET 7 (EOL) .NET 8 (LTS) .NET 9
Windows 10 ReportViewer 2022 ✓
Full WinForms + WPF
ReportViewer 2022 ✓
Recommended
Not supported
Use DevExpress/Telerik
Not supported
Use DevExpress/Telerik
Not supported
Use DevExpress/Telerik
Not supported
Use DevExpress/Telerik
Windows 11 ReportViewer 2022 ✓
Full WinForms + WPF
ReportViewer 2022 ✓
Recommended
Not supported
Use DevExpress/Telerik
Not supported
Use DevExpress/Telerik
Not supported
Use DevExpress/Telerik
Not supported
Use DevExpress/Telerik
Server 2019 ReportViewer 2022 ✓
Local mode + SSRS remote
ReportViewer 2022 ✓
Local mode + SSRS remote
Limited
Local mode only via .NET Fx shim — not recommended
Not supported Not supported Not supported
Server 2022 ReportViewer 2022 ✓
Local mode + SSRS remote
ReportViewer 2022 ✓
Local mode + SSRS remote
Limited
Local mode only via .NET Fx shim — not recommended
Not supported Not supported Not supported

✓ = Fully supported. Limited = Technically possible with workarounds but unsupported by Microsoft. Not supported = Runtime fails to load ReportViewer assembly.

Decision: ReportViewer vs Power BI Embedded vs DevExpress / Telerik / Stimulsoft

Vendor pricing note: Third-party reporting licenses range from approximately $800 (Stimulsoft) to $2,000+ (DevExpress, Telerik) per developer seat with annual subscription for updates. Power BI Embedded starts at approximately $735/month for A1 capacity. These figures are as of 2026; always obtain a current quote before budgeting. See our Software Selection Risk Notice.

The decision between the Microsoft ReportViewer control and alternatives is rarely about features — the RDLC format is capable of producing sophisticated paginated reports — and usually about roadmap alignment: what runtime does your application target, what is your team's tolerance for vendor dependency, and how much RDLC content have you already accumulated.

ReportViewer Decision Quadrant: WinForms vs WPF by Local vs Remote Processing A 2x2 quadrant matrix. X-axis: UI framework from WinForms (left) to WPF (right). Y-axis: processing from Local/offline (top) to Remote/SSRS (bottom). Each quadrant shows the recommended use case and typical technology choice. ReportViewer Decision Quadrant WinForms WPF Local / Offline Remote / SSRS WinForms + Local Best fit for Microsoft ReportViewer Standalone desktop apps RDLC from application data → NuGet 150.1500.0 + .NET Fx 4.8 ★ Primary ReportViewer use case WPF + Local ReportViewer via WindowsFormsHost Airspace limitation — assess first → Consider DevExpress/Telerik for native WPF viewer (no airspace) ⚠ Evaluate airspace impact WinForms + Remote SSRS server required (licensed) Reuses existing SSRS .rdl reports Enterprise: mixed portal+desktop → ReportViewer remote mode SSRS license cost — evaluate ROI WPF + Remote Least common — consider web viewer SSRS Report Server HTML viewer or WebView2 + SSRS portal URL → Power BI Paginated / Embedded Consider modern BI alternative
Decision quadrant: WinForms vs WPF × Local vs Remote processing. ReportViewer's strongest fit is the WinForms + Local quadrant.

The decision framework by scenario:

Use Microsoft ReportViewer if: Your application is a WinForms application on .NET Framework 4.7.2 or 4.8, you have existing RDLC reports you do not want to re-author, you need offline/disconnected support, and you are not planning a .NET 6+ migration in the next 24 months. The control is free, well-documented on Microsoft Learn, and the RDLC format is stable.

Use DevExpress XtraReports if: You need .NET 6/7/8 support, have an existing RDLC library you want to migrate, prefer a paid support relationship with a dedicated reporting vendor, or need advanced WPF rendering without airspace issues. DevExpress includes an RDLC-to-XtraReports import tool and a WPF viewer built natively on WPF rendering.

Use Telerik Reporting if: Your organization already has a DevCraft or Telerik license (it may be bundled), you need a web-based viewer alongside WinForms (Telerik's viewer runs in ASP.NET Core and Blazor as well), or you want tight integration with the Telerik UI component library.

Use Power BI Embedded if: Your reports are already in Power BI, your end users are business analysts accustomed to interactive dashboards (not paginated print-fidelity output), and your organization has Power BI Premium or Fabric capacity. Power BI Embedded excels at self-service analytics but is not a direct replacement for pixel-perfect paginated reports — that use case maps to Power BI Paginated Reports (which use the RDL schema) rather than standard Power BI reports.

Use FastReport.Net or Stimulsoft if: Cost is a primary constraint (both are less expensive than DevExpress or Telerik), you need RDLC migration tooling at a lower price point, or you need multi-platform support (FastReport has a Linux-compatible engine).

CriterionMS ReportViewerDevExpressTelerikPower BI Embedded
License costFree~$1,600/dev/yr~$1,800/dev/yr$735+/mo capacity
.NET 6/7/8 supportNoYesYesYes (JavaScript API)
RDLC importNativeImport toolImport toolRDL (via Paginated)
WPF native viewerVia WinForms hostYes (native WPF)Yes (native WPF)WebView2 only
Offline supportYes (local mode)YesYesNo
Paginated outputYesYesYesYes (Paginated tier)
Self-service analyticsNoLimitedLimitedYes

Frequently Asked Questions

Is ReportViewer free?

Yes. The Microsoft ReportViewer control is free to use and distributed via NuGet. The WinForms package (Microsoft.ReportingServices.ReportViewerControl.WinForms) and the WPF package (Microsoft.ReportingServices.ReportViewerControl.Wpf) are both published by Microsoft on NuGet.org at no cost. Local processing mode requires no additional server licenses. Remote processing mode requires an SSRS server, which is a separately licensed component of SQL Server Standard or SQL Server Enterprise.

Does ReportViewer work with .NET 6?

The official Microsoft package does not support .NET 6/7/8 natively. The NuGet package targets .NET Framework and will not load under the .NET 6+ runtime. For applications migrating to .NET 6 or later, third-party alternatives including DevExpress XtraReports, Telerik Reporting, and FastReport.Net offer RDLC-compatible viewers built for .NET 6/7/8. Applications staying on .NET Framework 4.7.2 or 4.8 are fully supported — .NET Framework 4.8 has extended support through 2031.

What is the difference between RDL and RDLC?

RDL (Report Definition Language) is Microsoft's XML schema used by SSRS for server-side report processing, with embedded data source connection strings. RDLC is the client-side variant — the "C" stands for "Client." RDLC files are designed for use with the ReportViewer control in WinForms and WPF applications, processing data locally within the application rather than on an SSRS server. RDLC files use the same XML schema as RDL but the data source section is empty — data binding happens programmatically via ReportDataSource objects at runtime. You can open both formats in the RDLC Report Designer extension for Visual Studio.

How do I install ReportViewer in Visual Studio 2022?

Two steps: First, install the RDLC Report Designer extension from Extensions > Manage Extensions in Visual Studio (search "RDLC Report Designer"). This gives you the visual design surface. Second, add the NuGet package: right-click your project > Manage NuGet Packages > search Microsoft.ReportingServices.ReportViewerControl.WinForms > install version 150.1500.0. Restart Visual Studio after installing the extension. The NuGet package adds the runtime; the extension adds the designer. You need both for development.

Can I use ReportViewer in WPF?

Yes, with a WindowsFormsHost wrapper. Add the NuGet package Microsoft.ReportingServices.ReportViewerControl.Wpf, or use the WinForms package with a WindowsFormsHost element in your XAML. Declare the wfi (WindowsFormsIntegration) and rv (ReportViewer) namespaces, wrap the ReportViewer inside a WindowsFormsHost element, and reference it by name in code-behind. Note the "airspace" limitation: WPF rendering effects (opacity animations, overlay popups) cannot be applied to the WinForms host region. If airspace is a blocker, DevExpress and Telerik offer native WPF viewer controls.

What replaced ReportViewer for cross-platform .NET?

Microsoft has not released an official cross-platform successor. For cross-platform .NET 6/7/8 including Linux/macOS, the recommended alternatives are: DevExpress XtraReports (with RDLC import, $1,600/developer/year), Telerik Reporting (native .NET 6+ with RDLC migration, $1,800/developer/year), FastReport.Net (Linux-compatible engine, lower cost), and Stimulsoft Reports (.NET 6+ with RDLC import). For organizations already on Azure, Power BI Paginated Reports use the RDL schema natively and can be embedded via Power BI Embedded APIs.

Is ReportViewer still supported?

ReportViewer 2022 (version 150.1500.0) is the current release as of 2026. Microsoft has not announced end-of-support, but active feature development has ceased — no new features have been added since 2022. The RDLC Report Designer extension still receives periodic Visual Studio compatibility updates. For applications on .NET Framework 4.7.2 or 4.8, the control remains fully functional within the .NET Framework support lifecycle, which extends to 2031 for .NET Framework 4.8. See Microsoft's .NET Framework lifecycle page.

How do I deploy a WinForms app with ReportViewer?

When installed via NuGet, the ReportViewer runtime DLLs (Microsoft.Reporting.WinForms.dll and dependencies) are automatically copied to the build output directory. For ClickOnce deployment, the NuGet package references are included in the publish manifest automatically. For MSI/installer deployment, include the full contents of the bin\Release\ folder. On the target machine, .NET Framework 4.7.2 or later must be installed — no separate ReportViewer redistributable is required when deploying NuGet-managed output. Include your .rdlc files in the installer with their relative paths preserved (e.g., Reports\SalesReport.rdlc).

Last reviewed and updated: May 8, 2026

About the Author

Sanjesh G. Reddy — has worked with the Microsoft ReportViewer control since the Visual Studio 2010 era, tracking the 2015 NuGet pivot and evaluating the ReportViewer 2022 package across WinForms billing and logistics applications. He maintains a cross-vendor RDLC compatibility test suite covering Microsoft ReportViewer, DevExpress XtraReports, and Telerik Reporting, and has guided multiple teams through .NET Framework 4.8 retention decisions when .NET 6 migrations exposed the ReportViewer runtime gap.

Learn more about our editorial team →