INTRODUCTION


ActiveReports 9 offers two different kinds of Section Based Reports. One is Code Based Report and the other is XML Based Report. The difference between the two is the code behind file which is associated with the former. The XML Based Report is basically an RPX file which contains the report layout and any script associated with the report. Though both report types have their own advantages, the XML based reports may be handy in some cases like you can make updates to the RPX files and redistribute them without recompiling & redistributing the assembly. Since the XML Based Report does not have any code behind, it uses its Script section to handle any associated functionality using script.

However there might be instances where we would want to use RPX files as Subreports and also set the datasource dynamically at runtime. It is quite clear that we would need to use Scripts to accomplish this task. But since scripts do not have access to any external classes, how shall we go about achieving the desired results? Well this blog topic tries to present an example which should clear things up.

USING AddNamedItem


If you haven't heard of this term before, I would suggest you to take a look at this blog article which specifically targets this topic. This method adds an object to the script's global namespace.  This further allows scripts to become aware of custom classes contained within a project. The sample which we are going to create in this blog creates subreports using XML based reports and allow users to switch between different datasources at runtime. The final output will look like the image below.

Output

IMPLEMENTATION


We will start by creating two separate classes which will return a DataTable. We name them "DataTable1.cs" and "DataTable2.cs" respectively. Since you can place any data inside the datatable, I am not providing the code inside these classes.

Next step is to go to the Form's code-behind and define a class which will hold the name of the datatable currently being used as the datasource. Once this class is updated with the required information, we will use the AddNamedItem method to use the corresponding datasource using script. The Form's code-behind will look like this:

  • Form's Code-Behind


public class DataSourceName
{
public string _dsName = "";
}

private void showReportToolStripMenuItem_Click(object sender, EventArgs e)
{
GrapeCity.ActiveReports.SectionReport rpt = new GrapeCity.ActiveReports.SectionReport();
System.Xml.XmlTextReader xtr = new System.Xml.XmlTextReader("..\\..\\rptMain.rpx");
rpt.LoadLayout(xtr);
xtr.Close();
rpt.AddNamedItem("DataSourceOne", new DataTable1());
rpt.AddNamedItem("DataSourceTwo", new DataTable2());
if ((RadioButton1.Checked == true))
{
DataSourceName ds = new DataSourceName();
ds._dsName = "DataTable1";
rpt.AddNamedItem("DS", ds);
}
else if ((RadioButton2.Checked == true))
{
DataSourceName ds = new DataSourceName();
ds._dsName = "DataTable2";
rpt.AddNamedItem("DS", ds);
}
rpt.Document.Printer.PrinterName = "";
viewer1.LoadDocument(rpt);
}


Once we are done with the setting of the datasource, it is now time to concentrate on the Main Report's Script section. You will notice how are we using the DS variable directly in the script, which we added using AddNamedItem in form's code-behind. This is how the Script will look:

  • Main Report's Script


private GrapeCity.ActiveReports.SectionReport rptSub;
public void ActiveReport_ReportStart()
{
this.SubReport1.ReportName = "..\\..\\rptSub.rpx";
rptSub = new GrapeCity.ActiveReports.SectionReport();
//Load the rpx file into the generic report
rptSub.LoadLayout(this.SubReport1.ReportName);
if (DS._dsName == "DataTable1")
{
rptSub.DataSource = DataSourceOne.GetDataTable1();
rptSub.Sections["Detail"].Controls["TextBox1"].DataField = "Name";
rptSub.Sections["Detail"].Controls["TextBox2"].DataField = "Age";
}

if (DS._dsName == "DataTable2")
{
rptSub.DataSource = DataSourceTwo.GetDataTable2();
rptSub.Sections["Detail"].Controls["TextBox1"].DataField = "Product";
rptSub.Sections["Detail"].Controls["TextBox2"].DataField = "Price";
}
}

public void Detail_Format()
{
GrapeCity.ActiveReports.SectionReportModel.SubReport rptSubCtl = this.SubReport1;
rptSubCtl.Report = rptSub;
}


So that is all we need to do. For a working example, please use the download link provided below.