Xafari Reports. Getting Started

This topic explains how to implement Xafari Report with scratch. It is important that you follow each step and carefully study the explanations. You can download XafariReportsSample solution, described in this article.

Create cross-platform XAF-application. Name it XafariReportsSample. In the Solution Explorer select XafariReportsSample.Module project and invoke Module Designer. Add Person class from DevExpress.Persistent.BaseImpl assembly.

Populate Person table: override UpdateDatabaseAfterUpdateSchema() method of the XafariReportsSample.Module.DatabaseUpdate.Updater class as follows.

  • c#
  • VB

public override void UpdateDatabaseAfterUpdateSchema()
{
  base.UpdateDatabaseAfterUpdateSchema();
  var personMary = ObjectSpace.FindObject<Person>(CriteriaOperator.Parse("FirstName == 'Mary' && LastName == 'Tellitson'"));
  if (personMary == null)
  {
    personMary = ObjectSpace.CreateObject<Person>();
    personMary.FirstName = "Mary";
    personMary.LastName = "Tellitson";
    personMary.Email = "mary_tellitson@md.com";
    personMary.Birthday = new DateTime(1980, 11, 27);
  }
  var personJohn = ObjectSpace.FindObject<Person>(CriteriaOperator.Parse("FirstName == 'John' && LastName == 'Nilsen'"));
  if (personJohn == null)
  {
    personJohn = ObjectSpace.CreateObject<Person>();
    personJohn.FirstName = "John";
    personJohn.LastName = "Nilsen";
    personJohn.Email = "john_nilsen@md.com";
    personJohn.Birthday = new DateTime(1981, 10, 3);
  }
}

Public Overrides Sub UpdateDatabaseAfterUpdateSchema()
  MyBase.UpdateDatabaseAfterUpdateSchema()
  Dim personMary = ObjectSpace.FindObject(Of Person)(CriteriaOperator.Parse("FirstName == 'Mary' && LastName == 'Tellitson'"))
  If personMary Is Nothing Then
    personMary = ObjectSpace.CreateObject(Of Person)()
    personMary.FirstName = "Mary"
    personMary.LastName = "Tellitson"
    personMary.Email = "mary_tellitson@md.com"
    personMary.Birthday = New DateTime(1980, 11, 27)
  End If
  Dim personJohn = ObjectSpace.FindObject(Of Person)(CriteriaOperator.Parse("FirstName == 'John' && LastName == 'Nilsen'"))
  If personJohn Is Nothing Then
    personJohn = ObjectSpace.CreateObject(Of Person)()
    personJohn.FirstName = "John"
    personJohn.LastName = "Nilsen"
    personJohn.Email = "john_nilsen@md.com"
    personJohn.Birthday = New DateTime(1981, 10, 3)
  End If
End Sub

Build and run application. Make sure it is working.

Add to the application Xafari.Arms functionality. This is required to organize the user's interaction with the reporting system. Add XafariReportsArmModule to XafariReportsSampleModule.

Add to the application Xafari Reports modules listed bellow:

  • XafariReportsModule, XafariReportsWinModule, XafariReportsWebModule – basic modules;
  • XafariReportsXafModule, XafariReportsXafWinModule, XafariReportsXafWebModule – Xtra Reports templates;
  • XafariReportsExcelModule, XafariReportsExcelWinModule, XafariReportsExcelWebModule – Excel reports templates.
  • XafariReportsFileModule, XafariReportsFileWinModule, XafariReportsFileWebModule – File reports templates.
  • XafariReportsAnalysisModule, XafariReportsAnalysisWinModule, XafariReportsAnalysisWebModule – Analysis reports templates.

Add DevExpress.Images, Devexpress.ExpressApp.Images, Xafari.Images assemblies to the win- and web-projects of the application. This ensures the correct display of graphics.

Now you can proceed directly to the implementation of the PersonsReport report. You must implement a data source, the report parameters, the algorithm populating the data source.

Add PersonsReportData class to XafariReportsSample.Module project. Replace the autogenerated file content with the following code (see PersonsReportDataSource.cs file).

  • c#
  • VB

using System.Collections.Generic;
using DevExpress.Persistent.BaseImpl;
using Xafari.Reports;
namespace XafariReportsSample.Module
{
  public class PersonsReportData : XafariReportDataBase
  {
    public string Caption { get; set; }
    public IList<Person> Persons { get; set; }
  }
}

Imports System.Collections.Generic
Imports DevExpress.Persistent.BaseImpl
Imports Xafari.Reports
Namespace XafariReportsSample.Module
  Public Class PersonsReportData
    Inherits XafariReportDataBase
    Public Property Caption As String
    Public Property Persons As IList(Of Person)
  End Class
End Namespace

Add PersonsReportParameters class to XafariReportsSample.Module project. Replace the autogenerated file content with the following code (see PersonsReportParameters.cs file)

  • c#
  • VB

using DevExpress.ExpressApp.DC;
using Xafari.Reports;
namespace XafariReportsSample.Module
{
  [DomainComponent, XafDisplayName("Persons report parameters")]
  public interface PersonsReportParameters : XafariReportParametersBase
  {
    string Filter { get; set; }
  }
}

Imports DevExpress.ExpressApp.DC
Imports Xafari.Reports
Namespace XafariReportsSample.Module
  <DomainComponent, XafDisplayName("Persons report parameters")> _
Public Interface PersonsReportParameters
    Inherits XafariReportParametersBase
    Property Filter As String
  End Interface
End Namespace

Add PersonsReportDataMiner class to XafariReportsSample.Module project. Replace the autogenerated file content with the following code (see PersonsReportDataMiner.cs file)

  • c#
  • VB

using DevExpress.Data.Filtering;
using DevExpress.Persistent.BaseImpl;
using Xafari;
using Xafari.Reports;
namespace XafariReportsSample.Module
{
  public class PersonsReportDataMiner : DataMinerOperationBase<PersonsReportData, PersonsReportParameters>
  {
    public override void CollectData()
    {
      ReportData.Caption = Parameters.Name;
      base.CollectData();
    }
    protected override CriteriaOperator GetCriteria(string propertyName)
    {
      if (propertyName == MemberHelper.MemberName<PersonsReportData>(m => m.Persons))
        return Parameters.Filter;
      return base.GetCriteria(propertyName);
    }
  }
}

Imports DevExpress.Data.Filtering
Imports DevExpress.Persistent.BaseImpl
Imports Xafari
Imports Xafari.Reports
Namespace XafariReportsSample.Module
  Public Class PersonsReportDataMiner
    Inherits DataMinerOperationBase(Of PersonsReportData, PersonsReportParameters)
    Public Overrides Sub CollectData()
      ReportData.Caption = Parameters.Name
      MyBase.CollectData()
    End Sub
    Protected Overrides Function GetCriteria(ByVal propertyName As String) As CriteriaOperator
      If propertyName = MemberHelper.MemberName(Of PersonsReportData)(Function(ByVal m) m.Persons) Then
        Return Parameters.Filter
      End If
      Return MyBase.GetCriteria(propertyName)
    End Function
  End Class
End Namespace

Note:

Xafari File Reports  also require to implement the file report generator. For other types of reports do not need it. Add PersonsReportFileGenerator class to XafariReportsSample.Module project. Replace the autogenerated file content with the following code (see PersonsReportFileGenerator.cs file)

  • c#
  • VB

using System.IO;
using System.Text;
using Xafari.Reports.File;
namespace XafariReportsSample.Module
{
  public class PersonsReportFileGenerator : XafariFileReportGenerator<PersonsReportData, PersonsReportParameters>
  {
    protected override void GenerateCore()
    {
      var stream = GetStream("PersonsBirthday.txt");
      var writer = new StreamWriter(stream, Encoding.UTF8);
      writer.WriteLine("=== {0} ===", ReportData.Caption);
      foreach (var person in ReportData.Persons)
      {
        writer.WriteLine("{0}, {1}", person.FullName, person.Birthday);
      }
      writer.Flush();
    }
  }
}

Imports System.IO
Imports System.Text
Imports Xafari.Reports.File
Namespace XafariReportsSample.Module
  Public Class PersonsReportFileGenerator
    Inherits XafariFileReportGenerator(Of PersonsReportData, PersonsReportParameters)
    Protected Overrides Sub GenerateCore()
      Dim stream = GetStream("PersonsBirthday.txt")
      Dim writer = New StreamWriter(stream, Encoding.UTF8)
      writer.WriteLine("=== {0} ===", ReportData.Caption)
      For Each person In ReportData.Persons
        writer.WriteLine("{0}, {1}", person.FullName, person.Birthday)
      Next
      writer.Flush()
    End Sub
  End Class
End Namespace

Implement a report class, which will "know" their data source, parameters and algorithm of population. Add PersonsReport class to XafariReportsSample.Module project. Replace the autogenerated file content with the following code (see PersonsReport.cs file).

  • c#
  • VB

using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using Xafari.Reports;
namespace XafariReportsSample.Module
{
  [XafDisplayName("Persons report"), ImageName("BO_Person")]
  public class PersonsReport : XafariReport<PersonsReportData, PersonsReportParameters, PersonsReportDataMiner>
  {
  }
}

Imports DevExpress.ExpressApp.DC
Imports DevExpress.Persistent.Base
Imports Xafari.Reports
Namespace XafariReportsSample.Module
  <XafDisplayName("Persons report"), ImageName("BO_Person")> _
Public Class PersonsReport
    Inherits XafariReport(Of PersonsReportData, PersonsReportParameters, PersonsReportDataMiner)
  End Class
End Namespace

Due to the fact that the PersonsReportParameters class is Domain Component, you must register it. Override Setup method of the XafariReportsSampleModule as follows

  • c#
  • VB

public override void Setup(XafApplication application)
{
  base.Setup(application);
  XafTypesInfo.Instance.RegisterEntity("PersonsReportParameters", typeof(PersonsReportParameters));
}

Public Overrides Sub Setup(ByVal application As XafApplication)
  MyBase.Setup(application)
  XafTypesInfo.Instance.RegisterEntity("PersonsReportParameters", GetType(PersonsReportParameters))
End Sub

Now it is necessary to provide the end-user interaction with the report. To do this, add a few items in the Xafari ARM navigation system.

Invoke Model Editor for the XafariReportsSample.Module project. Navigate to Xafari|ArmDesign|Arms node and add new Arm node, set Сaption property to "My Reports" value.

Add new View node to My Reports. Set View property to "XafariReportInfo_ListView" value, set Caption property to "Administration".

Add new Xafari Report node to My Reports. Set Report property to "PersonsReport" value, set Caption property to "Persons report".

Navigate to View|...|PersonsReportParameters_DetailView node and customise Layout, if it necessary.

Run application. Create Parameters and Templates and generate report.