Skip to main content

Customize Report Wizard Pages

  • 9 minutes to read

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

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.

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 {
    // Identifies the view for the "Choose Report Creation Mode" wizard page.
    // Displays a gallery of report types and handles user selection.
    public partial class ChooseReportCreationModePageView : WizardViewBase, IChooseReportCreationModePageView {
        // Specifies the header description displayed at the top of the wizard page.
        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;
        // Initializes the wizard page view and its elements.
        public ChooseReportCreationModePageView() {
            InitializeComponent();
        }
        // Initializes the gallery with available report types and applies the current skin style.
        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));
        }
        // Adds all available report type items (Standard and AI-generated) to the gallery.
        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);
        }
        // Handles the event when a gallery item is checked (selected).
        void OnItemCheckedChanged(object sender, GalleryItemEventArgs e) {
            if(!e.Item.Checked)
                return;
            CreationModeChanged?.Invoke(this, EventArgs.Empty);
        }

        void OnItemDoubleClick(object sender, GalleryItemClickEventArgs e) {
            MoveForward();
        }
    }
}

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.

using DevExpress.AIIntegration.Reporting.Wizard.Presenters;
using DevExpress.Data.WizardFramework;
using DevExpress.XtraReports.Wizards;
using DevExpress.XtraReports.Wizards.Presenters;
// Handles user interaction and navigation logic based on the selected mode.
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;
        // Called when the page is shown. Initializes the view's creation mode and subscribes to changes.
        public override void Begin() {
            View.CreationMode = Model.GetIsAIReportType() ? ReportCreationMode.AI : ReportCreationMode.Standard;
            View.CreationModeChanged += OnCreationModeChanged;
        }
        // Called when leaving the page. Unsubscribes from events and updates the model with the selected mode.
        public override void Commit() {
            View.CreationModeChanged-= OnCreationModeChanged;
            Model.SetIsAIReportType(View.CreationMode == ReportCreationMode.AI);
        }
        // Determines the next wizard page type based on the selected report creation mode.
        public override Type GetNextPageType() {
            return View.CreationMode == ReportCreationMode.Standard
                ? typeof(ChooseReportTypePage<XtraReportModel>)
                : typeof(AIChooseDataSourceOptionPage<XtraReportModel>);
        }

        void OnCreationModeChanged(object? sender, EventArgs e) => RaiseChanged();
    }
}

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:

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);
                    }
                }
            }
    }
}

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.

reportDesigner1.AddService<IWizardCustomizationService>(new WizardCustomizationService());

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

Report wizard customization with AI

See Also