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.