How to: Customize the Export Action Behavior

In XAF WinForms and ASP.NET applications, data from List Views can be exported using the Export Action the built-in ExportController provides. This Action is activated by default if the List Editor that implements the IExportable interface presents the current List View. Currently, all built-in WinForms List Editors and most ASP.NET List Editors support this interface (excludes the built-in Mobile List Editors). The Action's ChoiceActionBase.Items collection is filled based on the IExportable.SupportedExportFormats collection of the current List View's List Editor.

You can customize this Action's behavior using the ExportController's events. Note that there are two ExportController descendants: the WinExportController is used in WinForms applications, exports data to a file stream and invokes a Save File Dialog before exporting; and the WebExportController is used in ASP.NET applications and exports data to a memory stream.

When customizing the export functionality, ensure that the changes are intended for the base or platform-specific Controller. In this topic, the ExportController.CustomGetDefaultFileName, ExportController.CustomExport and ExportController.Exported events are handled for Export Action customization, both in WinForms and ASP.NET applications.

The sections below describe how to access the ExportController and customize the Export Action behavior by handling the Controller's events.

Tip

A complete sample project is available in the DevExpress Code Examples database at http://www.devexpress.com/example=E2335.

Customize the Name of the File Used for Exporting Data

In WinForms applications, a Save File Dialog is invoked before exporting data to a file. In this dialog, the default file name is specified. It is generated from the caption of the List View from which data is currently exported. In ASP.NET applications, data is exported to a Memory Stream which can be downloaded as a file. This file's default name is generated in the same way as in the WinForms application. Subscribe to the ExportController.CustomGetDefaultFileName event to customize this file name. The base platform-independent ExportController class exposes this event. So, the file name that you provide in this event's handler is used in WinForms and ASP.NET applications. The following code demonstrates how to access the ExportController and handle its event:

using DevExpress.ExpressApp.SystemModule;
//...
public partial class CustomizeExportController : ViewController {
    public CustomizeExportController() {
        InitializeComponent();
        TargetViewType = ViewType.ListView;
    }
    private ExportController exportController;
    protected override void OnActivated() {
         base.OnActivated();
         exportController = Frame.GetController<ExportController>();
         if (exportController != null) {
             exportController.CustomGetDefaultFileName += exportController_CustomGetDefaultFileName;
         }
    }
    void exportController_CustomGetDefaultFileName(
        object sender, CustomGetDefaultFileNameEventArgs e) {
        //Provide a custom file name
        e.FileName = e.FileName + "_" + DateTime.Now.ToString("MM.dd.yy");
    }
    protected override void OnDeactivated() {
         if (exportController != null) {
             exportController.CustomGetDefaultFileName -= exportController_CustomGetDefaultFileName;
         }
        base.OnDeactivated();
    }
}

The following image illustrates that the name specified in the CustomGetDefaultFileName event handler is used as the exported file's default name:

CustomExport_FileName

If you need to customize the default file name for WinForms or ASP.NET applications only, access the WinExportController or WebExportController, respectively. These Controllers are ExportController's descendants - they expose the CustomGetDefaultFileName event as well.

Customize Export Options Using the CustomExport Event for both the WinForms and ASP.NET Applications

You can customize the exporting options specified for the target export format using the ExportOptionsBase class descendants. To do this, subscribe to the ExportController.CustomExport event and use the handler's CustomExportEventArgs.ExportOptions parameter to access them. If you need to change options for both WinForms and ASP.NET applications, subscribe to the ExportController's CustomExport event. Use the handler's CustomExportEventArgs.ExportTarget parameter to get the export format currently used in the export operation. For example, you can change XSL export options as shown below.

using DevExpress.ExpressApp.SystemModule;
using DevExpress.XtraPrinting;
// ...
public partial class CustomizeExportController : ViewController {
    public CustomizeExportController() {
        InitializeComponent();
        TargetViewType = ViewType.ListView;
    }
    private ExportController exportController;
    protected override void OnActivated() {
        base.OnActivated();
        exportController = Frame.GetController<ExportController>();
        exportController.CustomExport += new EventHandler<CustomExportEventArgs>(CustomExport);
    }
    protected virtual void CustomExport(object sender, CustomExportEventArgs e) {
        //Customize Export Options
        if (e.ExportTarget == ExportTarget.Xls) {
            XlsExportOptions options = e.ExportOptions as XlsExportOptions;
            if (options == null) {
               options = new XlsExportOptions();
            }
            options.SheetName = View.Caption;
            options.ShowGridLines = true;
            e.ExportOptions = options;
        }
    }
    protected override void OnDeactivated() {
        exportController.CustomExport -= new EventHandler<CustomExportEventArgs>(CustomExport);
        base.OnDeactivated();
    }
}

In the code above, the exported View's caption is used as the sheet's name in the exported XLS file.

Export_6

If you need to customize the exporting options in WinForms or ASP.NET applications only, access the WinExportController or WebExportController, respectively. These Controllers are ExportController's descendants, and they expose the CustomExport event as well.

You can customize export options using the XlsExportOptionsEx class members as an alternative to the XlsExportOptions's members.

Customize Export Options Using the CustomExport Event for a WinForms Application

This section demonstrates how to customize exporting options specific to a particular export format, for example, the exporting options the built-in WinForms List Editors' controls provide. Subscribe to the CustomExport event and use the event handler's CustomExportEventArgs.Printable parameter to access these controls. For instance, when data is exported from the TreeListEditor, the Printable parameter provides access to the TreeList control. This control's TreeList.OptionsPrint property allows you to set the required exporting options.

In a GridListEditor, the GridControl is used to export data. Use the GridView's GridView.OptionsPrint property to access the GridControl's exporting options.

The code below demonstrates how to use the GridOptionsPrint.ExpandAllGroups property of the object returned by the GridView's OptionsPrint property.

When a GridListEditor presents a List View, data rows can be grouped and the groups can be collapsed. The the Export Action's default behavior is to expand all the collapsed groups in the exported file. You can invoke a message to notify an end-user when GridListEditor has collapsed groups and then ask whether to keep them collapsed in the exported file. Handle the ExportController.CustomExport event to do this.

It is necessary to iterate through grid group rows to detect collapsed groups. The group rows have negative handles in the Grid View (see Working with Groups in Code). The expansion status of a group row can be determined by the GridView.GetRowExpanded method. Display the message box using the Messaging.GetUserChoice method when a collapsed group is detected, and set the GridOptionsPrint.ExpandAllGroups property based on the user's selection.

Implement a Controller in a WinForms module to change the ExpandAllGroups export option of the grid control used in the WinForms application. In this Controller, access the WinExportController to subscribe to its CustomExport event.

using DevExpress.XtraGrid.Views.Grid;
using DevExpress.ExpressApp.Win.SystemModule;
using DevExpress.ExpressApp.Win.Editors;
using DevExpress.ExpressApp.Win;
using System.Windows.Forms;
// ...
public partial class CustomizeExportControllerWin : ViewController {
     public CustomizeExportControllerWin() {
        InitializeComponent();
        TargetViewType = ViewType.ListView;
    }
    private WinExportController winExportController;
    protected override void OnActivated() {
        base.OnActivated();
        winExportController = Frame.GetController<WinExportController>();
        winExportController.CustomExport += winExportController_CustomExport;
    }
    void winExportController_CustomExport(object sender, CustomExportEventArgs e) {
        //Show a message before exporting a Grid List Editor
        GridListEditor gridListEditor = 
            ((DevExpress.ExpressApp.ListView)View).Editor as GridListEditor;
        if (gridListEditor != null) {
            GridView gridView = gridListEditor.GridView;
            if (HasCollapsedGroups(gridView)) {
                string message =
                   "There are collapsed groups in the grid. " +
                    "Expand all groups in the exported file?";
                gridView.OptionsPrint.ExpandAllGroups =
                   WinApplication.Messaging.GetUserChoice(message, GetMessageBoxCaption(),
                   MessageBoxButtons.YesNo)
                   == DialogResult.Yes;
            }
        }
    }
    private bool HasCollapsedGroups(GridView gridView) {
        if (gridView.GroupCount > 0) {
            int rowHandle = -1;
            while (gridView.IsValidRowHandle(rowHandle)) {
                if (!gridView.GetRowExpanded(rowHandle)) return true;
                rowHandle--;
            }
        }
        return false;
    }
    private string GetMessageBoxCaption() {
        return String.Format(
            "{0} {1}", winExportController.ExportAction.Caption,
                winExportController.ExportAction.SelectedItem);
    }
    protected override void OnDeactivated() {
        winExportController.CustomExport -= winExportController_CustomExport;
        base.OnDeactivated();
    }
}

End-users will see the following message box when exporting a List View containing collapsed groups:

Export_2

Note

Refer to the How to: Localize Custom String Constants topic to see how to make this message text localizable.

If the choice is "Yes", all grid rows will be exported.

Export_4

If the choice is "No", the rows belonging to the collapsed groups will not be included in the exported file.

Export_3

Customize Export Options Using the CustomExport Event for an ASP.NET Application

In ASP.NET applications, the controls that are used to export data from List Editors are so-called exporters. You can use them to change default export settings. Subscribe to the ExportController.CustomExport event and use the event handler's CustomExportEventArgs.Printable parameter to access the exporter of the currently exported List Editor. For instance, when data is exported from the ASPxGridListEditor, the Printable parameter provides access to the ASPxGridViewExporter exporter.

The code below demonstrates how to use the ASPxGridViewExporter's ASPxGridViewExporter.ExportSelectedRowsOnly property. This property is set to the true value to export only rows that are the currently selected in the exported grid.

Implement a Controller in a Web module to use an ASPxGridViewExporter export option, used by the ASPxGridListEditor in the ASP.NET application. In this Controller, access the WebExportController to subscribe to its CustomExport event.

using DevExpress.ExpressApp.Web.SystemModule;
//add a reference to the DevExpress.Web.Export assembly
using DevExpress.Web;
// ...
public partial class CustomizeExportControllerWeb : ViewController {
    public CustomizeExportControllerWeb() {
        InitializeComponent();
        TargetViewType = ViewType.ListView;
    }
    private WebExportController webExportController;
    protected override void OnActivated() {
        base.OnActivated();
        webExportController = Frame.GetController<WebExportController>();
        webExportController.CustomExport += webExportController_CustomExport;
    }
    void webExportController_CustomExport(object sender, CustomExportEventArgs e) {
        //Export only selected rows
        ASPxGridViewExporter exporter = e.Printable as ASPxGridViewExporter;
        if (exporter != null) {
            exporter.ExportSelectedRowsOnly = true;
        }
    }
    protected override void OnDeactivated() {
        webExportController.CustomExport -= webExportController_CustomExport;
        base.OnDeactivated();
    }
}

With the code above, the Export Action exports only selected grid rows:

CustomExport_SelectedRows

Customize the Export Action Behavior Using the Exported Event for the WinForms Application

After the export operation has finished, you can ask end-users whether or not the saved file should be opened. Handle the ExportController.Exported event to do this. The handler's CustomExportEventArgs.Stream parameter can be used to determine the exported file name.

using System.IO;
using DevExpress.ExpressApp.Win;
using System.Windows.Forms;
using DevExpress.ExpressApp.Win.SystemModule;
//...
public partial class CustomizeExportControllerWin : ViewController {
    // ...
    private WinExportController winExportController;
    protected override void OnActivated() {
        base.OnActivated();
        // ...
        winExportController.Exported += 
            new EventHandler<CustomExportEventArgs>(winExportController_Exported);
    }
    void winExportController_Exported(object sender, 
            DevExpress.ExpressApp.SystemModule.CustomExportEventArgs e) {
        if (e.Stream is FileStream) {
            string fileName = ((FileStream)e.Stream).Name;
            if (File.Exists(fileName)) {
                e.Stream.Close();
                if (WinApplication.Messaging.GetUserChoice("Open the exported file?",
                        GetMessageBoxCaption(), MessageBoxButtons.YesNo) == DialogResult.Yes)
                    Process.Start(fileName);
            }
        }
    }
    protected override void OnDeactivated()  {
        winExportController.Exported -= 
            new EventHandler<CustomExportEventArgs>(winExportController_Exported);
        // ...
        base.OnDeactivated();
    }
}

The following image illustrates the message box shown after the export is finished.

Export_5

Note

Refer to the How to: Localize Custom String Constants topic to see how to localize the message text.

If the end-user clicks "Yes", the exported file opens in an application associated with its type.

See Also