Back to Devexpress

Customize Report Wizard Pages

xtrareports-115670-desktop-reporting-winforms-reporting-end-user-report-designer-for-winforms-api-and-customization-customize-report-wizards-pages.md

latest21.5 KB
Original Source

Customize Report Wizard Pages

  • Nov 10, 2025
  • 8 minutes to read

This document describes how to add a custom page to the Report Wizard.

Important

Customization options described in this help topic are available to owners of DevExpress WinForms, DXperience, and Universal subscriptions (subscriptions that include DevExpress WinForms UI Controls). The DevExpress Reporting Subscription does not support UI customization in Report Viewer or End-User Report Designer. You can use ReportPrintTool and ReportDesignTool classes to display Print Preview and End-User Report Designer in their default configurations.

Refer to the following help topic for information on subscription options: Installation - Subscriptions that Include Reporting Components.

Create a Custom Report Wizard Page

A wizard page definition consists of a View and a Presenter. The View defines the page’s visual interface. The Presenter determines the program logic behind the wizard page.

To create a custom wizard page, implement the following classes:

Page View Class

A page view class is an DevExpress.XtraEditors.XtraUserControl descendant populated with data editors. A custom page view class should be inherited from WizardViewBase, a base class that implements the DevExpress.DataAccess.Wizard.Views.IWizardPageView interface. A page view class should also implement a specific interface required to associate a presenter with a page view. These interfaces are contained in the DevExpress.DataAccess.Wizard.Views namespace.

Implementation Example

In the following example, the ChooseReportCreationModePage page overrides the Report Wizard start page and allows users to select an AI-powered report generation option. The page contains two options: Standard Report and AI-generated Report.

View Example: Add AI-powered Options to the Report Wizard and Customize the First Page

ChooseReportCreationModePageView identifies a custom page view (a WizardViewBase descendant that implements IChooseReportCreationModePageView). ChooseReportCreationModePageView defines page GUI elements such as “Standard Report” and “AI-generated Report” items, text header, and other elements.

csharp
using System.ComponentModel;
using DevExpress.AIIntegration.Reporting.Wizard;
using DevExpress.AIIntegration.WinForms.Reporting.Wizard.Images;
using DevExpress.DataAccess.UI.Wizard.Views;
using DevExpress.Utils.Svg;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraReports.Design;

namespace AIWizardCustomizationExample.Customization {
    public partial class ChooseReportCreationModePageView : WizardViewBase, IChooseReportCreationModePageView {
        public override string HeaderDescription => "Choose Standard or AI-generated report type.";

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public ReportCreationMode CreationMode {
            get { return (ReportCreationMode)reportTypeGallery.GetValue(ReportCreationMode.Standard); }
            set { reportTypeGallery.SetValue(value); }
        }

        public event EventHandler CreationModeChanged;

        public ChooseReportCreationModePageView() {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);
            reportTypeGallery.ClearGallery();
            reportTypeGallery.InitializeGallery(list => AddReportItems(list));
            reportTypeGallery.SetSkinStyle(LookAndFeel.ActiveSkinName);
        }

        protected void AddItem(IList<GalleryItem> list, string text, SvgImage svgImage, object tag) {
            list.Add(reportTypeGallery.CreateItem(text, svgImage, tag));
        }

        protected virtual void AddReportItems(IList<GalleryItem> list) {
            AddItem(list, "Standard Report", SvgImageLocator.GetWizardImage("StandardReport"), ReportCreationMode.Standard);
            AddItem(list, "AI-generated Report", AIWizardImages.IconReportAI, ReportCreationMode.AI);
        }

        void OnItemCheckedChanged(object sender, GalleryItemEventArgs e) {
            if(!e.Item.Checked)
                return;
            CreationModeChanged?.Invoke(this, EventArgs.Empty);
        }

        void OnItemDoubleClick(object sender, GalleryItemClickEventArgs e) {
            MoveForward();
        }
    }
}
vb
Imports System.ComponentModel
Imports DevExpress.AIIntegration.WinForms.Reporting.Wizard.Images
Imports DevExpress.DataAccess.UI.Wizard.Views
Imports DevExpress.Utils.Svg
Imports DevExpress.XtraBars.Ribbon
Imports DevExpress.XtraReports.Design

Namespace AIWizardCustomizationExample.Customization

    Public Partial Class ChooseReportCreationModePageView
        Inherits WizardViewBase
        Implements IChooseReportCreationModePageView

        Public Overrides ReadOnly Property HeaderDescription As String
            Get
                Return "Choose Standard or AI-generated report type."
            End Get
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
        Public Property CreationMode As ReportCreationMode Implements IChooseReportCreationModePageView.CreationMode
            Get
                Return CType(reportTypeGallery.GetValue(ReportCreationMode.Standard), ReportCreationMode)
            End Get

            Set(ByVal value As ReportCreationMode)
                reportTypeGallery.SetValue(value)
            End Set
        End Property

        Public Event CreationModeChanged As EventHandler Implements IChooseReportCreationModePageView.CreationModeChanged

        Public Sub New()
            InitializeComponent()
        End Sub

        Protected Overrides Sub OnLoad(ByVal e As EventArgs)
            MyBase.OnLoad(e)
            reportTypeGallery.ClearGallery()
            reportTypeGallery.InitializeGallery(Sub(list)
                                                    AddReportItems(list)
                                                End Sub
)
            reportTypeGallery.SetSkinStyle(LookAndFeel.ActiveSkinName)
        End Sub

        Protected Sub AddItem(ByVal list As IList(Of GalleryItem), ByVal text As String, ByVal svgImage As SvgImage, ByVal tag As Object)
            list.Add(reportTypeGallery.CreateItem(text, svgImage, tag))
        End Sub

        Protected Overridable Sub AddReportItems(ByVal list As IList(Of GalleryItem))
            AddItem(list, "Standard Report", SvgImageLocator.GetWizardImage("StandardReport"), ReportCreationMode.Standard)
            AddItem(list, "AI-generated Report", AIWizardImages.IconReportAI, ReportCreationMode.AI)
        End Sub

        Private Sub OnItemCheckedChanged(ByVal sender As Object, ByVal e As GalleryItemEventArgs)
            If Not e.Item.Checked Then Return
            RaiseEvent CreationModeChanged(Me, EventArgs.Empty)
        End Sub

        Private Sub OnItemDoubleClick(ByVal sender As Object, ByVal e As GalleryItemClickEventArgs)
            MoveForward()
        End Sub
    End Class
End Namespace

Presenter Class

A page presenter is inherited from the base WizardPageBase<TView, TModel> class or from the existing wizard presenters. A page presenter should override the WizardPageBase<TView,TModel>.GetNextPageType method that returns the type of the subsequent wizard page and defines the order in which wizard pages are displayed.

Implementation Example

In the following example, the ChooseReportCreationModePage page overrides the Report Wizard start page and allows users to select an AI-powered report generation option. The page contains two options: Standard Report and AI-generated Report.

View Example: Add AI-powered Options to the Report Wizard and Customize the First Page

ChooseReportCreationModePage identifies a page presenter (WizardPageBase descendant). AI-generated ChooseReportCreationModePage defines the logic used to navigate to the next page based on the selected item.

csharp
using DevExpress.AIIntegration.Reporting.Wizard.Presenters;
using DevExpress.Data.WizardFramework;
using DevExpress.XtraReports.Wizards;
using DevExpress.XtraReports.Wizards.Presenters;

namespace AIWizardCustomizationExample.Customization {
    public class ChooseReportCreationModePage<TModel> : WizardPageBase<IChooseReportCreationModePageView, TModel> where TModel: XtraReportModel {
        public ChooseReportCreationModePage(IChooseReportCreationModePageView view) : base(view) { }

        public override bool MoveNextEnabled => true;
        public override bool FinishEnabled => false;

        public override void Begin() {
            View.CreationMode = Model.GetIsAIReportType() ? ReportCreationMode.AI : ReportCreationMode.Standard;
            View.CreationModeChanged += OnCreationModeChanged;
        }

        public override void Commit() {
            View.CreationModeChanged-= OnCreationModeChanged;
            Model.SetIsAIReportType(View.CreationMode == ReportCreationMode.AI);
        }

        public override Type GetNextPageType() {
            return View.CreationMode == ReportCreationMode.Standard
                ? typeof(ChooseReportTypePage<XtraReportModel>)
                : typeof(AIChooseDataSourceOptionPage<XtraReportModel>);
        }

        void OnCreationModeChanged(object? sender, EventArgs e) => RaiseChanged();
    }
}
vb
Imports DevExpress.AIIntegration.Reporting.Wizard.Presenters
Imports DevExpress.Data.WizardFramework
Imports DevExpress.XtraReports.Wizards
Imports DevExpress.XtraReports.Wizards.Presenters

Namespace AIWizardCustomizationExample.Customization

    Public Class ChooseReportCreationModePage(Of TModel As XtraReportModel)
        Inherits WizardPageBase(Of IChooseReportCreationModePageView, TModel)

        Public Sub New(ByVal view As IChooseReportCreationModePageView)
            MyBase.New(view)
        End Sub

        Public Overrides ReadOnly Property MoveNextEnabled As Boolean
            Get
                Return True
            End Get
        End Property

        Public Overrides ReadOnly Property FinishEnabled As Boolean
            Get
                Return False
            End Get
        End Property

        Public Overrides Sub Begin()
            View.CreationMode = If(Model.GetIsAIReportType(), ReportCreationMode.AI, ReportCreationMode.Standard)
            AddHandler Me.View.CreationModeChanged, AddressOf OnCreationModeChanged
        End Sub

        Public Overrides Sub Commit()
            RemoveHandler Me.View.CreationModeChanged, AddressOf OnCreationModeChanged
            Model.SetIsAIReportType(View.CreationMode = ReportCreationMode.AI)
        End Sub

        Public Overrides Function GetNextPageType() As Type
            Return If(View.CreationMode = ReportCreationMode.Standard, GetType(ChooseReportTypePage(Of XtraReportModel)), GetType(AIChooseDataSourceOptionPage(Of XtraReportModel)))
        End Function

        Private Sub OnCreationModeChanged(ByVal sender As Object, ByVal e As EventArgs)
            RaiseChanged()
        End Sub
    End Class
End Namespace

You can choose a page and a presenter, and create descendants for your custom page. The following help topics describe page views and presenters available in the Data Source and Report Wizards:

Incorporate a Custom Page Into the Report Wizard

To customize the Report and/or Data Source wizard, implement the IWizardCustomizationService interface. Use the IWizardCustomizationService.CustomizeDataSourceWizard method to modify the Data Source wizard and the IWizardCustomizationService.CustomizeReportWizard method to modify the Report wizard. Both methods receive a tool argument of the IWizardCustomization<TModel> type, which gives access to the IWizardCustomization<TModel>.StartPage property. You can use this property to set the first wizard page.

Call the IWizardCustomization<TModel>.RegisterPage<TPageType, TPageInstance> and IWizardCustomization<TModel>.RegisterPageView<TViewType, TViewInstance> methods to register a presenter and a view for each custom page. The RegisterPage method associates the type that identifies the page within the wizard (returned by the previous page’s GetNextPageType method) with the actual page type. In the same way, the RegisterPageView method associates the type that identifies the page view (the corresponding presenter’s type parameter) with the actual type. You can substitute any standard wizard page with a custom descendant.

Implementation Example

In the following example, the ChooseReportCreationModePage page overrides the Report Wizard start page and allows users to select an AI-powered report generation option. The page contains two options: Standard Report and AI-generated Report.

View Example: Add AI-powered Options to the Report Wizard and Customize the First Page

The following code registers pages with AI-related options:

csharp
using DevExpress.AIIntegration.Reporting.Wizard.Presenters;
using DevExpress.AIIntegration.Reporting.Wizard.Views;
using DevExpress.AIIntegration.WinForms;
using DevExpress.AIIntegration.WinForms.Reporting;
using DevExpress.AIIntegration.WinForms.Reporting.Wizard;
using DevExpress.AIIntegration.WinForms.Reporting.Wizard.Views;
using DevExpress.Data.Utils;
using DevExpress.DataAccess.UI.Wizard;
using DevExpress.DataAccess.Wizard.Model;
using DevExpress.XtraReports.Design;
using DevExpress.XtraReports.UI;
using DevExpress.XtraReports.Wizards;

namespace AIWizardCustomizationExample.Customization {
    internal class WizardCustomizationService : IWizardCustomizationService {
        public void CustomizeReportWizard(IWizardCustomization<XtraReportModel> tool) {
            tool.StartPage = typeof(ChooseReportCreationModePage<XtraReportModel>);
            tool.RegisterPage<ChooseReportCreationModePage<XtraReportModel>, ChooseReportCreationModePage<XtraReportModel>>();
            tool.RegisterPageView<IChooseReportCreationModePageView, ChooseReportCreationModePageView>();
        }

            public void CustomizeDataSourceWizard(IWizardCustomization<XtraReportModel> tool) { }

            public bool TryCreateDataSource(IDataSourceModel model, out object dataSource, out string dataMember) {
                dataSource = null;
                dataMember = null;
                return false;
            }

            public bool TryCreateReport(IDesignerHost designerHost, XtraReportModel model, object dataSource, string dataMember) {
                if(model.GetIsAIReportType()) {
                    DoWithOverlay(designerHost, () => {
                        var builder = new AIReportBuilder(designerHost, dataSource, dataMember);
                        builder.Build((XtraReport)designerHost.RootComponent, model);
                    });
                    return true;
                }
                return false;
            }

            void DoWithOverlay(IDesignerHost designerHost, Action action) {
                Control control = designerHost.GetService<ReportTabControlBase>();
                using(var waitForm = new AIOverlayForm()) {
                    waitForm.ShowLoading(control);
                    try {
                        action();
                        waitForm.Close();
                    } catch(Exception ex) {
                        waitForm.ShowError(control, ex.Message, false);
                    }
                }
            }
    }
}
vb
Imports System.ComponentModel.Design
Imports DevExpress.AIIntegration.Reporting
Imports DevExpress.AIIntegration.Reporting.Wizard
Imports DevExpress.AIIntegration.Reporting.Wizard.Presenters
Imports DevExpress.AIIntegration.Reporting.Wizard.Views
Imports DevExpress.AIIntegration.WinForms
Imports DevExpress.AIIntegration.WinForms.Reporting
Imports DevExpress.AIIntegration.WinForms.Reporting.Wizard
Imports DevExpress.AIIntegration.WinForms.Reporting.Wizard.Views
Imports DevExpress.Data.Utils
Imports DevExpress.DataAccess.UI.Wizard
Imports DevExpress.DataAccess.Wizard.Model
Imports DevExpress.XtraReports.Design
Imports DevExpress.XtraReports.UI
Imports DevExpress.XtraReports.Wizards

Namespace AIWizardCustomizationExample.Customization

    Friend Class WizardCustomizationService
        Implements IWizardCustomizationService
        Public Sub CustomizeReportWizard(ByVal tool As IWizardCustomization(Of XtraReportModel)) Implements IWizardCustomizationService.CustomizeReportWizard
            tool.StartPage = GetType(ChooseReportCreationModePage(Of XtraReportModel))
            tool.RegisterPage(Of ChooseReportCreationModePage(Of XtraReportModel), ChooseReportCreationModePage(Of XtraReportModel))()
            tool.RegisterPageView(Of IChooseReportCreationModePageView, ChooseReportCreationModePageView)()

        End Sub

        Public Sub CustomizeDataSourceWizard(ByVal tool As IWizardCustomization(Of XtraReportModel)) Implements IWizardCustomizationService.CustomizeDataSourceWizard
        End Sub

        Public Function TryCreateDataSource(ByVal model As IDataSourceModel,  ByRef dataSource As Object,  ByRef dataMember As String) As Boolean Implements IWizardCustomizationService.TryCreateDataSource
            dataSource = Nothing
            dataMember = Nothing
            Return False
        End Function

        Public Function TryCreateReport(ByVal designerHost As IDesignerHost, ByVal model As XtraReportModel, ByVal dataSource As Object, ByVal dataMember As String) As Boolean Implements IWizardCustomizationService.TryCreateReport
            If model.GetIsAIReportType() Then
                DoWithOverlay(designerHost, Sub()
                    Dim builder = New AIReportBuilder(designerHost, dataSource, dataMember)
                    builder.Build(CType(designerHost.RootComponent, XtraReport), model)
                End Sub)
                Return True
            End If
            Return False
        End Function
        Private Sub DoWithOverlay(ByVal designerHost As IDesignerHost, ByVal action As Action)
            Dim control As System.Windows.Forms.Control = designerHost.GetService(Of ReportTabControlBase)()

            Using waitForm = New AIOverlayForm()
                waitForm.ShowLoading(control)

                Try
                    action()
                    waitForm.Close()
                Catch ex As Exception
                    waitForm.ShowError(control, ex.Message, False)
                End Try
            End Using
        End Sub
    End Class
End Namespace

Register the Wizard Customization Extension

In the previous steps, you created a new page with custom logic for the Report Wizard. To apply this wizard customization to the End-User Report Designer for WinForms, pass an instance of your IWizardCustomizationSevice implementation to the report designer’s XRDesignMdiController.AddService method as shown below.

csharp
reportDesigner1.AddService<IWizardCustomizationService>(new WizardCustomizationService());
vb
reportDesigner1.AddService(Of IWizardCustomizationService)(New WizardCustomizationService())

When you invoke the Report Wizard, the created custom page appears:

See Also

Wizard Customization Overview