How to: Display Non-Persistent Objects in a Report

  • 4 min to read

This topic describes how to create a report based on non-persistent data, which is not queried from a database using your ORM data model. This can be helpful for analysis and reporting data obtained from dynamic runtime calculations, stored procedures, arbitrary SQL queries or third-party services. To be able to use the Reports V2 Module in this scenario, you will need to define your data structure with the help of non-persistent classes and then create required object instances using the NonPersistentObjectSpace.ObjectsGetting event. A similar approach is demonstrated in the How to: Display a Non-Persistent Object's List View from the Navigation topic.

  • Declare a non-persistent class (e.g., MyNonPersistentObject), and decorate it with the DomainComponentAttribute and VisibleInReportsAttribute attributes.

    using DevExpress.ExpressApp.DC;
    using DevExpress.Persistent.Base;
    // ...
    [DomainComponent, VisibleInReportsAttribute]
    public class MyNonPersistentObject {
        public string Name { get; set; }

    The INotifyPropertyChanged, IXafEntityObject and IObjectSpaceLink interface implementations were omitted in this example. However, it is recommended to support these interfaces in real-world applications (see PropertyChanged Event in Business Classes and Non-Persistent Objects).

  • Create a predefined static report in Visual Studio or create a report at runtime using the MyNonPersistentObject as the report's data type.

    In Visual Studio, set the DataSourceBase.ObjectTypeName property of the CollectionDataSource component to MyNonPersistentObject.


    At runtime, choose MyNonPersistentObject in the Data Type combo box of the Report Wizard.



    ViewDataSource is not supposed to work with non-persistent data. Always use CollectionDataSource.

    If you now preview the created report, it will display no data. Proceed to see how to populate the MyNonPersistentObject collection.

  • Open the WinApplication.cs (WinApplication.vb), WebApplication.cs (WebApplication.vb) and/or MobileApplication.cs (MobileApplication.vb) code. Ensure that the NonPersistentObjectSpaceProvider is registered in the overridden CreateDefaultObjectSpaceProvider method (in addition to the existing XPObjectSpaceProvider or EFObjectSpaceProvider). Currently, this code is added automatically by the Solution Wizard, but it may be missing if you have created your project using an older version of XAF.

    protected override void CreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgs args) {
        // ...
        args.ObjectSpaceProviders.Add(new NonPersistentObjectSpaceProvider(TypesInfo, null));
  • Create a Window Controller. In the overridden OnActivated method, subscribe to the XafApplication.ObjectSpaceCreated event. In the event handler, if the ObjectSpaceCreatedEventArgs.ObjectSpace is of the NonPersistentObjectSpace type, subscribe to the NonPersistentObjectSpace.ObjectsGetting event and populate the e.Objects collection as required.

    using DevExpress.ExpressApp;
    // ...
    public class NonPersistentClassWindowController : WindowController {
        public NonPersistentClassWindowController()
            : base() {
            TargetWindowType = WindowType.Main;
        protected override void OnActivated() {
            Application.ObjectSpaceCreated += Application_ObjectSpaceCreated;
        private void Application_ObjectSpaceCreated(Object sender, ObjectSpaceCreatedEventArgs e) {
            if (e.ObjectSpace is NonPersistentObjectSpace) {
                ((NonPersistentObjectSpace)e.ObjectSpace).ObjectsGetting += ObjectSpace_ObjectsGetting;
        private void ObjectSpace_ObjectsGetting(Object sender, ObjectsGettingEventArgs e) {
            if (e.ObjectType == typeof(MyNonPersistentObject)) {
                BindingList<MyNonPersistentObject> objects = new BindingList<MyNonPersistentObject>();
                for (int i = 1; i < 10; i++) {
                    objects.Add(new MyNonPersistentObject() { Name = string.Format("Object {0}", i) });
                e.Objects = objects;
        protected override void OnDeactivated() {
            Application.ObjectSpaceCreated -= Application_ObjectSpaceCreated;

The result is demonstrated in the image below.