MVVM - Bind to a Report in a ViewModel
- 4 minutes to read
The DevExpress MVVM Framework allows you to bind the DocumentPreviewControl to a report in a view model. The view model contains the code required to retrieve a report from the storage.
The following code defines the binding in XAML:
<dx:ThemedWindow x:Class="ShowReportPreview_MVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:models="clr-namespace:ShowReportPreview_MVVM.Models"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxp="http://schemas.devexpress.com/winfx/2008/xaml/printing"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
Title="MainWindow" WindowState="Maximized"
DataContext="{dxmvvm:ViewModelSource Type=models:ReportCatalogViewModel}">
<!-- ... -->
<dxp:DocumentPreviewControl Name="preview"
RequestDocumentCreation="True"
DocumentSource="{Binding Report}" />
Thw DocumentPreviewControl.DocumentSource property is bound to the ReportCatalogViewModel.Report property.
The ReportCatalogViewModel
is the ViewModel class implemented as follows:
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.XtraReports.UI;
// ...
[POCOViewModel]
public class ReportCatalogViewModel : ViewModelBase {
// ...
public virtual XtraReport Report { get; protected set; }
// ...
}
For more information on POCO View Models, review the following help topic: Runtime-generated POCO View Models.
The ViewModel retrieves reports from a database storage and creates a collection of ReportCatalogItem
objects. The ReportCatalogItem class is defined as follows:
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
// ...
public class ReportCatalogItem {
[Key]
public string ID { get; set; }
public string ReportName { get; set; }
public byte[] Layout { get; set; }
}
Use the bindable AvailableReports property to access the ReportCatalogItem
collection, as shown in the following code sample:
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.XtraReports.UI;
using ShowReportPreview_MVVM.Data;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
// ...
[POCOViewModel]
public class ReportCatalogViewModel : ViewModelBase {
readonly ReportCatalogDbContext dbContext = new ReportCatalogDbContext();
public virtual IEnumerable<ReportCatalogItem> AvailableReports { get; protected set; }
public virtual XtraReport Report { get; protected set; }
protected override void OnInitializeInRuntime() {
base.OnInitializeInRuntime();
dbContext.ReportItems.Load();
AvailableReports = dbContext.ReportItems.Local;
}
// ...
}
The DevExpress MVVM Framework enables you to create commands that can be bound to any element in the View. Review the following help topic for more information: POCO Commands.
The following code implements the ShowPreview command that opens a report with the DocumentPreviewControl located in the View, and the ShowPreviewInNewWindow command that uses the DevExpress.Mvvm.IDialogService to open a report in a modal window:
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.XtraReports.UI;
using ShowReportPreview_MVVM.Data;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
// ...
[POCOViewModel]
public class ReportCatalogViewModel : ViewModelBase {
// ...
public virtual IEnumerable<ReportCatalogItem> AvailableReports { get; protected set; }
// ...
public void ShowPreview(string reportId) {
Report = LoadReport(reportId);
}
protected bool CanShowPreview(string reportId) => AvailableReports.Any(x => x.ID == reportId);
public void ShowPreviewInNewWindow(string reportId) {
XtraReport report = LoadReport(reportId);
DocumentPreviewDialogViewModel dialogModel = new DocumentPreviewDialogViewModel(report);
IDialogService previewDialogService = GetService<IDialogService>("previewDialogService");
previewDialogService.ShowDialog(null, "Document Preview", dialogModel);
}
protected bool CanShowPreviewInNewWindow(string reportId) => CanShowPreview(reportId);
XtraReport LoadReport(string reportId) {
ReportCatalogItem reportItem = AvailableReports.Single(x => x.ID == reportId);
using(var stream = new MemoryStream(reportItem.Layout)) {
return XtraReport.FromStream(stream);
}
}
}
The application appears as follows: