Skip to main content
All docs
V25.1
  • 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