Skip to main content
All docs
V24.2

DevExpress v24.2 Update — Your Feedback Matters

Our What's New in v24.2 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.

Take the survey Not interested

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