wpf-9652-controls-and-libraries-printing-exporting-examples-how-to-create-drill-down-reports.md
This example illustrates how to create interactive drill-down documents by handling the DocumentPreviewControl.DocumentPreviewMouseClick and DocumentPreviewControl.DocumentPreviewMouseMove events.
#region reference
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Mvvm.POCO;
using DevExpress.Xpf.Printing;
#endregion reference
namespace PreviewClickDemo {
[POCOViewModel]
#region code
public class MainWindowViewModel {
readonly Northwind.CategoriesDataTable categories;
readonly IList<Northwind.CategoriesRow> expandedCategories = new List<Northwind.CategoriesRow>();
public SimpleLink Link { get; private set; }
public static MainWindowViewModel Create(DataTemplate detailDataTemplate) {
return ViewModelSource.Create(() => new MainWindowViewModel(detailDataTemplate));
}
protected MainWindowViewModel(DataTemplate detailDataTemplate) {
// Populate the data source.
var nwind = DataSource.CreateNorthwindData();
categories = nwind.Categories;
// Assign a new SimpleLink instance to the link object,
// with the specified data template and the number of detail records.
Link = new SimpleLink(detailDataTemplate, categories.Count);
// Handle the link's CreateDetail event, where it obtains its data.
Link.CreateDetail += OnLinkCreateDetail;
}
void OnLinkCreateDetail(object sender, CreateAreaEventArgs e) {
var category = categories[e.DetailIndex];
e.Data = new CategoryWrapper(expandedCategories.Contains(category), category);
}
// Provide the drill-down functionality in the OnPreviewMouseClick event handler.
public void OnPreviewMouseClick(DocumentPreviewMouseEventArgs args) {
if (string.IsNullOrEmpty((string)args.ElementTag)) {
return;
}
var categoryID = int.Parse(args.ElementTag.ToString());
var category = categories.FindByCategoryID(categoryID);
if (expandedCategories.Contains(category)) {
expandedCategories.Remove(category);
}
else {
expandedCategories.Add(category);
}
Link.CreateDocument(true);
}
// Change the mouse cursor when it hovers the label
// that serves as a link to expand/collapse the detail data.
public void OnPreviewMouseMove(DocumentPreviewMouseEventArgs args) {
if (string.IsNullOrEmpty((string)args.ElementTag)) {
return;
}
Mouse.SetCursor(Cursors.Hand);
}
}
#endregion code
}
namespace PreviewClickDemo {
public class CategoryWrapper {
public bool IsExpanded { get; set; }
public Northwind.CategoriesRow Row { get; private set; }
public CategoryWrapper(bool isExpanded, Northwind.CategoriesRow row) {
IsExpanded = isExpanded;
Row = row;
}
}
}
Namespace PreviewClickDemo
Public Class CategoryWrapper
Public Property IsExpanded() As Boolean
Private privateRow As Northwind.CategoriesRow
Public Property Row() As Northwind.CategoriesRow
Get
Return privateRow
End Get
Private Set(ByVal value As Northwind.CategoriesRow)
privateRow = value
End Set
End Property
Public Sub New(ByVal isExpanded As Boolean, ByVal row As Northwind.CategoriesRow)
Me.IsExpanded = isExpanded
Me.Row = row
End Sub
End Class
End Namespace
#Region "reference"
Imports System.Collections.Generic
Imports System.Windows
Imports System.Windows.Input
Imports DevExpress.Mvvm.DataAnnotations
Imports DevExpress.Mvvm.POCO
Imports DevExpress.Xpf.Printing
#End Region ' reference
Namespace PreviewClickDemo
#Region "code"
<POCOViewModel> _
Public Class MainWindowViewModel
Private ReadOnly categories As Northwind.CategoriesDataTable
Private ReadOnly expandedCategories As IList(Of Northwind.CategoriesRow) = New List(Of Northwind.CategoriesRow)()
Private privateLink As SimpleLink
Public Property Link() As SimpleLink
Get
Return privateLink
End Get
Private Set(ByVal value As SimpleLink)
privateLink = value
End Set
End Property
Public Shared Function Create(ByVal detailDataTemplate As DataTemplate) As MainWindowViewModel
Return ViewModelSource.Create(Function() New MainWindowViewModel(detailDataTemplate))
End Function
Protected Sub New(ByVal detailDataTemplate As DataTemplate)
' Populate the data source.
Dim nwind = DataSource.CreateNorthwindData()
categories = nwind.Categories
' Assign a new SimpleLink instance to the link object,
' with the specified data template and the number of detail records.
Link = New SimpleLink(detailDataTemplate, categories.Count)
' Handle the link's CreateDetail event, where it obtains its data.
AddHandler Link.CreateDetail, AddressOf OnLinkCreateDetail
End Sub
Private Sub OnLinkCreateDetail(ByVal sender As Object, ByVal e As CreateAreaEventArgs)
Dim category = categories(e.DetailIndex)
e.Data = New CategoryWrapper(expandedCategories.Contains(category), category)
End Sub
' Provide the drill-down functionality in the OnPreviewMouseClick event handler.
Public Sub OnPreviewMouseClick(ByVal args As DocumentPreviewMouseEventArgs)
If String.IsNullOrEmpty(CStr(args.ElementTag)) Then
Return
End If
Dim categoryID = Integer.Parse(args.ElementTag.ToString())
Dim category = categories.FindByCategoryID(categoryID)
If expandedCategories.Contains(category) Then
expandedCategories.Remove(category)
Else
expandedCategories.Add(category)
End If
Link.CreateDocument(True)
End Sub
' Change the mouse cursor when it hovers the label
' that serves as a link to expand/collapse the detail data.
Public Sub OnPreviewMouseMove(ByVal args As DocumentPreviewMouseEventArgs)
If String.IsNullOrEmpty(CStr(args.ElementTag)) Then
Return
End If
Mouse.SetCursor(Cursors.Hand)
End Sub
End Class
#End Region ' code
End Namespace
The following image illustrates the result.