Skip to main content
All docs
V23.2

MVVM - Use Report Designer API from ViewModel

  • 5 minutes to read

The DevExpress MVVM Framework allows you to access the ReportDesigner methods from commands defined in the ViewModel. You can develop your own API that extends the built-in functionality of ReportDesigner and optimally meets your requirements.

In this example the Behavior mechanism initializes a service that implements ReportDesigner actions. The service is defined as follows:

using DevExpress.Mvvm.UI;
using DevExpress.Mvvm.UI.Interactivity;
using DevExpress.Xpf.Reports.UserDesigner;
using DevExpress.XtraReports.UI;
using System;
using System.Collections.Generic;
using System.IO;

namespace ManipulateReportDesignerDocuments_MVVM {
    public interface IReportDesignerAPIService {
        IEnumerable<ReportDesignerDocument> Documents { get; }
        ReportDesignerDocument ActiveDocument { get; }
        ReportDesignerDocument NewReport(XtraReport report = null);
        ReportDesignerDocument Open();
        ReportDesignerDocument Open(Stream stream);
    }

    public class ReportDesignerAPIService : ServiceBase, IReportDesignerAPIService {
        ReportDesigner Designer => (ReportDesigner)AssociatedObject;

        public IEnumerable<ReportDesignerDocument> Documents => Designer.Documents;

        public ReportDesignerDocument ActiveDocument => Designer.ActiveDocument;

        public ReportDesignerDocument NewReport(XtraReport report = null) {
            Func<XtraReport> reportFactory = null;
            if(report != null)
                reportFactory = () => report;
            return Designer.NewDocument(reportFactory);
        }

        public ReportDesignerDocument Open() {
            return Designer.OpenDocument();
        }

        public ReportDesignerDocument Open(Stream stream) {
            return Designer.OpenDocument(stream);
        }
    }
}

The ReportDesignerAPIService is specified as custom behavior. For more information on the Behavior mechanism in DevExpress MVVM Framework, review the following help topic: Behaviors.

The following code uses the ReportDesignerAPIService class as a custom Behavior for the ReportDesigner element in the View:

<dx:ThemedWindow x:Class="ManipulateReportDesignerDocuments_MVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ManipulateReportDesignerDocuments_MVVM"
        xmlns:dxrud="http://schemas.devexpress.com/winfx/2008/xaml/reports/userdesigner" 
        xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
        xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
        mc:Ignorable="d" WindowKind="Tabbed" WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800">
        <!-- ... -->
        <dxrud:ReportDesigner>
            <dxrud:ReportDesignerBrowserView CloseWindowWhenLastTabIsClosed="False" />
            <dxrud:ReportDesigner.DocumentSource>
                <Binding Path="DefaultReport" />
            </dxrud:ReportDesigner.DocumentSource>
            <dxmvvm:Interaction.Behaviors>
                <local:ReportDesignerAPIService />
            </dxmvvm:Interaction.Behaviors>
        </dxrud:ReportDesigner>
        <!-- ... -->
</dx:ThemedWindow>

The MainViewModel ViewModel class gets the ReportDesignerAPIService service and implements MVVM commands based on the service methods:

using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Xpf.Reports.UserDesigner;
using DevExpress.XtraReports.UI;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Resources;

namespace ManipulateReportDesignerDocuments_MVVM {
    public class MainViewModel : ViewModelBase {
        public XtraReport DefaultReport { get; set; }

        IReportDesignerAPIService ReportDesignerAPI => ServiceContainer.GetService<IReportDesignerAPIService>();

        protected override void OnInitializeInRuntime() {
            base.OnInitializeInRuntime();
            DefaultReport = new XtraReport();
        }

        [Command]
        public void NewReport() {
            ReportDesignerAPI.NewReport();
        }
        public bool CanNewReport() => ReportDesignerAPI != null;

        [Command]
        public void OpenReport() {
            ReportDesignerAPI.Open();
        }
        public bool CanOpenReport() => ReportDesignerAPI != null;

        [Command]
        public void OpenReportFromStream() {
            var stream = Application.GetResourceStream(new Uri("Resources/Invoice.repx", UriKind.Relative))?.Stream;
            if(stream != null) {
                using(stream) {
                    ReportDesignerAPI.Open(stream);
                }
            }
        }
        public bool CanOpenReportFromStream() => ReportDesignerAPI != null;

        [Command]
        public void CloseActiveDocument() {
            ReportDesignerAPI.ActiveDocument.Close(true);
        }
        public bool CanCloseActiveDocument() => ReportDesignerAPI?.ActiveDocument != null;

        [Command]
        public void ActivateFirstDocumentTab() {
            ReportDesignerDocument firstTab = ReportDesignerAPI.Documents.First();
            firstTab.Activate();
        }
        public bool CanActivateFirstDocumentTab() => ReportDesignerAPI?.Documents.Any() ?? false;

        [Command]
        public void SwitchActiveDocumentView() {
            ReportDesignerDocument activeDocument = ReportDesignerAPI.ActiveDocument;
            activeDocument.ViewKind = activeDocument.ViewKind == ReportDesignerDocumentViewKind.Designer
                ? ReportDesignerDocumentViewKind.Preview
                : ReportDesignerDocumentViewKind.Designer;
        }
        public bool CanSwitchActiveDocumentView() => ReportDesignerAPI?.ActiveDocument != null;
    }
}

For more information on auto-generated commands, review the following help topic: POCO Commands.

The application appears as follows:

Use Report Designer API from ViewModel - Screenshot

View Example: How to Use MVVM Framework to Create Custom Commands for Report Designer