Back to Devexpress

DataSourceManager Class

xtrareports-devexpress-dot-xtrareports-e51ab3ce.md

latest21.8 KB
Original Source

DataSourceManager Class

Contains methods that allow you to manage report data sources at runtime.

Namespace : DevExpress.XtraReports

Assembly : DevExpress.XtraReports.v25.2.dll

NuGet Package : DevExpress.Reporting.Core

Declaration

csharp
public static class DataSourceManager
vb
Public Module DataSourceManager

Remarks

The DataSourceManager class includes the following methods:

GetDataSourcesReturns all report data sources.AddDataSourcesAdds the specified data sources to a report.ReplaceDataSourceReplaces a report’s current data source with the specified data source.GetDataSourceAssignablesReturns a report and its elements (subreports, controls, bands, parameters) to which a data source can be assigned.GetDataSourceAssignablesByDataSourceReturns a report and its elements (subreports, controls, bands, parameters) to which the specified data source is assigned.

See the following sections for information on some typical tasks related to runtime configuration of report data sources and an explanation on how to use the above methods to solve these tasks:

For instructions on how to use the DataSourceManager class methods in WinForms, WPF, and ASP.NET Core applications, refer to the following section: Platform-Specific Code Samples (WinForms, WPF, ASP.NET Core).

Add Data Sources to a Report

Assume that you want to add data sources to the End-User Report Designer at runtime, so that these data sources are displayed in the Field List and can be used in the report right after the designer is invoked.

To accomplish this task, call the AddDataSources method. Pass the report to which you want to add the data sources as the first argument, then specify the data sources.

The following code sample adds two JSON data sources to a report:

csharp
using DevExpress.DataAccess.Json;
using DevExpress.XtraReports;
//...

var report = new XtraReport1();

var jsonDataSource1 = new JsonDataSource { /* ... */ };
var jsonDataSource2 = new JsonDataSource { /* ... */ };

DataSourceManager.AddDataSources(report, jsonDataSource1, jsonDataSource2);
vb
Imports DevExpress.DataAccess.Json
Imports DevExpress.XtraReports
'...

Private report = New XtraReport1()

Private jsonDataSource1 = New JsonDataSource()
Private jsonDataSource2 = New JsonDataSource()

DataSourceManager.AddDataSources(report, jsonDataSource1, jsonDataSource2)

Replace a Report Data Source

The ReplaceDataSource method allows you to replace a report’s current data source with a new data source (this action might be required if you want to switch from mock data to real data in your application at runtime).

Call the ReplaceDataSource method if the types of the new and initial report data sources are different. If the types of the new and replaced data sources match, you can update settings of the existing report data source.

The following code sample shows how to replace a report’s initial data source with a JSON data source:

csharp
using DevExpress.XtraReports;
using DevExpress.DataAccess.Json;
//...

var report = new XtraReport1();

var jsonDataSource = new JsonDataSource;

DataSourceManager.ReplaceDataSource(report, report.DataSource, jsonDataSource);
vb
Imports DevExpress.XtraReports
Imports DevExpress.DataAccess.Json
'...

Private report = New XtraReport1()

Private jsonDataSource = New JsonDataSource()

DataSourceManager.ReplaceDataSource(report, report.DataSource, jsonDataSource)

Update Settings of Report Data Sources

If you want to bind your report and its elements (subreports, controls, bands, or parameters) to data sources and then update their settings at runtime (for example, to switch from “development” to “production” settings), do the following:

  1. Call the GetDataSources method to retrieve all report data sources.
  2. Iterate through the retrieved data sources.
  3. Update settings of each data source as needed.

The following code sample shows how to get all report data sources (except for subreport data sources), iterate through these data sources, and update settings (the ConnectionName property) of each data source whose type is SqlDataSource.

csharp
using DevExpress.DataAccess.Sql;
using DevExpress.XtraReports;
//...

var report = new XtraReport1();

var dataSources = DataSourceManager.GetDataSources(report, includeSubReports: false);

foreach (var dataSource in dataSources) {
    if (dataSource is SqlDataSource) {
        (dataSource as SqlDataSource).ConnectionName = "nwind";
    }
}
vb
Imports DevExpress.DataAccess.Sql
Imports DevExpress.XtraReports
'...

Private report = New XtraReport1()

Private dataSources = DataSourceManager.GetDataSources(report, includeSubReports:= False)

For Each dataSource In dataSources
    If TypeOf dataSource Is SqlDataSource Then
        TryCast(dataSource, SqlDataSource).ConnectionName = "nwind"
    End If
Next dataSource

Update Settings of Report and Subreport Data Sources

If you want to update settings of a report data source and subreport data sources, do the following:

  1. Call the GetDataSourceAssignables method to get all report elements to which a data source can be assigned.
  2. Filter the elements by a required type (XtraReport in our case).
  3. Update data source settings for each filtered element.

Note that this task is similar to the previous one. However, you need to access only data sources of subreports and the report itself rather than all report data sources. Thus, you cannot call the GetDataSources method, since it can return a data source whose element’s type differs from XtraReport (for example, DetailReportBand or XRCrossTab).

The following code sample shows how to retrieve a report and all its subreports (elements of the XtraReport type) and update settings (the ConnectionName property) of their data sources. In this example, we assume that the type of each data source is SqlDataSource.

csharp
using DevExpress.DataAccess.Sql;
using DevExpress.XtraReports.UI;
using DevExpress.XtraReports;
//...

var report = new XtraReport1();

var dataBoundReports = DataSourceManager.GetDataSourceAssignables<XtraReport>(
    report: report,
    includeSubReports: true
);

foreach (var dataBoundReport in dataBoundReports) {
    (dataBoundReport.DataSource as SqlDataSource).ConnectionName = "nwind";
}
vb
Imports DevExpress.DataAccess.Sql
Imports DevExpress.XtraReports.UI
Imports DevExpress.XtraReports
'...

Private report = New XtraReport1()

Private dataBoundReports = DataSourceManager.GetDataSourceAssignables(Of XtraReport)(report:= report, includeSubReports:= True)

For Each dataBoundReport In dataBoundReports
    TryCast(dataBoundReport.DataSource, SqlDataSource).ConnectionName = "nwind"
Next dataBoundReport

Platform-Specific Code Samples (WinForms, WPF, ASP.NET Core)

Add Data Sources to a Report on Invoking the Report Designer

WinForms

csharp
using System;
using System.Windows.Forms;
using DevExpress.XtraReports;
using DevExpress.DataAccess.Json;
//...

private void Form1_Load(object sender, EventArgs e) {
    var report = new XtraReport1();
    var reportDesignTool = new ReportDesignTool(report);

    var jsonDataSource1 = new JsonDataSource { /* ... */ };
    var jsonDataSource2 = new JsonDataSource { /* ... */ };

    DataSourceManager.AddDataSources(report, jsonDataSource1, jsonDataSource2);

    reportDesignTool.ShowRibbonDesigner();
}
vb
Imports System
Imports System.Windows.Forms
Imports DevExpress.XtraReports
Imports DevExpress.DataAccess.Json
'...

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
    Dim report = New XtraReport1()
    Dim reportDesignTool As New ReportDesignTool(report)

    Dim jsonDataSource1 = New JsonDataSource()
    Dim jsonDataSource2 = New JsonDataSource()

    DataSourceManager.AddDataSources(report, jsonDataSource1, jsonDataSource2)

    reportDesignTool.ShowRibbonDesigner()
End Sub

WPF

csharp
using DevExpress.DataAccess.Json;
using DevExpress.XtraReports;
using System.Windows;
//...

private void Window_Loaded(object sender, RoutedEventArgs e) {
    var report = new XtraReport1();

    var jsonDataSource1 = new JsonDataSource { /* ... */ };
    var jsonDataSource2 = new JsonDataSource { /* ... */ };

    DataSourceManager.AddDataSources(report, jsonDataSource1, jsonDataSource2);

    reportDesigner.OpenDocument(report);
}
vb
Imports DevExpress.DataAccess.Json
Imports DevExpress.XtraReports
Imports System.Windows
'...

Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim report = New XtraReport1()

    Dim jsonDataSource1 = New JsonDataSource()
    Dim jsonDataSource2 = New JsonDataSource()
    DataSourceManager.AddDataSources(report, jsonDataSource1, jsonDataSource2)

    reportDesigner.OpenDocument(report)
End Sub

ASP.NET Core

In an ASP.NET Core reporting application, add data sources to a report in a service’s method that retrieves a report from a storage and returns this report to the designer. The following code sample shows how to do it in the GetData method of the ReportStorageWebExtension service.

csharp
using DevExpress.XtraReports;
using DevExpress.DataAccess.Json;
//...

public override byte[] GetData(string url) {
    //...

    if (ReportsFactory.Reports.ContainsKey(url)) {
        using var ms = new MemoryStream();
        using XtraReport report = ReportsFactory.Reportsurl;

        var jsonDataSource1 = new JsonDataSource { /* ... */ };
        var jsonDataSource2 = new JsonDataSource { /* ... */ };

        DataSourceManager.AddDataSources(report, jsonDataSource1, jsonDataSource2);

        report.SaveLayoutToXml(ms);
        return ms.ToArray();
    }

    //...
}

Update Data Source Settings on Showing Report Preview

WinForms

csharp
using DevExpress.XtraReports;
using DevExpress.DataAccess.Json;
using DevExpress.XtraReports.Design;
using DevExpress.XtraReports.UI;
using DevExpress.XtraReports.UserDesigner;
using System.Windows.Forms;
using System;
//...

private void Form1_Load(object sender, EventArgs e) {
    // Create a ReportDesignTool instance and
    // implement a DesignPanelLoaded event handler as
    // shown below. After that, invoke the designer.

    var reportDesignTool = new ReportDesignTool(new XtraReport1());
    reportDesignTool.DesignRibbonForm.DesignMdiController.DesignPanelLoaded += DesignMdiController_DesignPanelLoaded;
    reportDesignTool.ShowRibbonDesigner();
}

private void DesignMdiController_DesignPanelLoaded(object sender, DevExpress.XtraReports.UserDesigner.DesignerLoadedEventArgs e) {
    ReportTabControl tabControl = ((XRDesignPanel) sender).GetService(typeof(ReportTabControl)) as ReportTabControl;
    tabControl.PreviewReportCreated += TabControl_PreviewReportCreated;
}

private void TabControl_PreviewReportCreated(object sender, EventArgs e) {
    var reportTabControl = sender as ReportTabControl;
    var report = reportTabControl.PreviewReport;

    // Update data source settings of the retrieved report here.
    var jsonDataSource = new JsonDataSource { /* ... */ };
    DataSourceManager.ReplaceDataSource(report, report.DataSource, jsonDataSource);
}
vb
Imports DevExpress.XtraReports
Imports DevExpress.DataAccess.Json
Imports DevExpress.XtraReports.Design
Imports DevExpress.XtraReports.UI
Imports DevExpress.XtraReports.UserDesigner
Imports System.Windows.Forms
Imports System
'...

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
    ' Create a ReportDesignTool instance and
    ' implement a DesignPanelLoaded event handler as
    ' shown below. After that, invoke the designer.

    Dim reportDesignTool As New ReportDesignTool(New XtraReport1())
    AddHandler reportDesignTool.DesignRibbonForm.DesignMdiController.DesignPanelLoaded, AddressOf DesignMdiController_DesignPanelLoaded
    reportDesignTool.ShowRibbonDesigner()
End Sub

Private Sub DesignMdiController_DesignPanelLoaded(ByVal sender As Object, ByVal e As DevExpress.XtraReports.UserDesigner.DesignerLoadedEventArgs)
    Dim tabControl As ReportTabControl = TryCast(DirectCast(sender, XRDesignPanel).GetService(GetType(ReportTabControl)), ReportTabControl)
    AddHandler tabControl.PreviewReportCreated, AddressOf TabControl_PreviewReportCreated
End Sub

Private Sub TabControl_PreviewReportCreated(ByVal sender As Object, ByVal e As EventArgs)
    Dim reportTabControl As ReportTabControl = TryCast(sender, ReportTabControl)
    Dim report = reportTabControl.PreviewReport

    ' Update data source settings of the retrieved report here.
    Dim jsonDataSource As New JsonDataSource()
    DataSourceManager.ReplaceDataSource(report, report.DataSource, jsonDataSource)
End Sub

WPF

csharp
using DevExpress.DataAccess.Json;
using DevExpress.XtraReports;
using System.Windows;
//...

public MainWindow() {
    InitializeComponent();

    // Implement the designer's ActiveDocumentChanged event handler as shown below.
    reportDesigner.ActiveDocumentChanged += reportDesigner_ActiveDocumentChanged;
}

private void reportDesigner_ActiveDocumentChanged(object sender, DependencyPropertyChangedEventArgs e) {
    if (reportDesigner.ActiveDocument != null) {
        reportDesigner.ActiveDocument.ReportCloned += ActiveDocument_ReportCloned;
    }
}

private void ActiveDocument_ReportCloned(object? sender, DevExpress.Xpf.Reports.UserDesigner.ReportClonedEventArgs e) {
    var report = e.Cloned;

    // Update data source settings of the retrieved report here.
    var jsonDataSource = new JsonDataSource { /* ... */ };
    DataSourceManager.ReplaceDataSource(report, report.DataSource, jsonDataSource);
}
vb
Imports DevExpress.DataAccess.Json
Imports DevExpress.XtraReports
Imports System.Windows
'...

public MainWindow()
    InitializeComponent()

    ' Implement the designer's ActiveDocumentChanged event handler as shown below.
    AddHandler reportDesigner.ActiveDocumentChanged, AddressOf reportDesigner_ActiveDocumentChanged
End Sub

Private Sub reportDesigner_ActiveDocumentChanged(ByVal sender As Object, ByVal e As DependencyPropertyChangedEventArgs)
    If reportDesigner.ActiveDocument IsNot Nothing Then
        AddHandler reportDesigner.ActiveDocument.ReportCloned, AddressOf ActiveDocument_ReportCloned
    End If
End Sub

private void ActiveDocument_ReportCloned(object sender, DevExpress.Xpf.Reports.UserDesigner.ReportClonedEventArgs e)
    Dim report = e.Cloned

    ' Update data source settings of the retrieved report here.
    Dim jsonDataSource As New JsonDataSource()
    DataSourceManager.ReplaceDataSource(report, report.DataSource, jsonDataSource)
End Sub

ASP.NET Core (Basic Approach)

In an ASP.NET Core reporting application, inherit from the PreviewReportCustomizationService class and override its CustomizeReport method. In this method, update settings of report data sources as needed.

csharp
public class CustomPreviewReportCustomizationService : PreviewReportCustomizationService {
    public override void CustomizeReport(XtraReport report) {
        var jsonDataSource = new JsonDataSource;
        DataSourceManager.ReplaceDataSource(report, report.DataSource, jsonDataSource);
    }
}

Add this class to the Services collection in the application startup file:

csharp
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddScoped<PreviewReportCustomizationService, CustomPreviewReportCustomizationService>();

var app = builder.Build();

ASP.NET Core – Inject Data from the Entity Framework Core DbContext into a Report (Advanced Example)

Assume that you wish to implement an ASP.NET Core reporting application that meets the following requirements:

  • You want to create and edit reports in the End-User Report Designer and show their preview.
  • You can get data for reports only from a custom data provider, that is, from a method of a service stored in the ServiceContainer collection.

To meet these requirements, you should use the ObjectDataSource component.

  1. This component can generate a schema for your data and serialize data types allowing you to create and edit reports in the designer without filling the component with actual data.
  2. You can fill this component with data on switching to a report preview. To accomplish this task, do the following:
  3. Inherit from the PreviewReportCustomizationService class and override its CustomizeReport method.
  4. In this method, extract a data object of a required type from the ServiceContainer collection.
  5. Assign this object to the component’s DataSource property. To find the required component, call the DataSourceManager.GetDataSources method.

Refer to the following example for more details:

View Example: Inject Data from the Entity Framework Core DbContext into a Report Using the Object Data Source

In particular, see code samples in the following files:

Inheritance

Object DataSourceManager

See Also

DataSourceManager Members

DevExpress.XtraReports Namespace