ActiveReports 6 Online Help Send comments on this topic.
Run Time Layouts
See Also
ActiveReports 6 > ActiveReports User Guide > Samples and Walkthroughs > Walkthroughs > Run Time or Ad Hoc Reporting > Run Time Layouts

Glossary Item Box

ActiveReports objects and controls are completely accessible at run time. You can modify the properties of any of the report sections or controls to produce a dynamic report. The section Format event allows you to modify the properties of the section and its controls, including height, visibility, and other visual properties. The Format event is the only event in which you can modify the printable area of a section. Once this event has run, any changes to the section's height are not reflected in the report output. This walkthrough illustrates how to create a report layout at run time based on user input.

Note: Add controls dynamically in the ReportStart event. Otherwise, results may be unpredictable. For more information on events, see the Sequence of Events topic.

This walkthrough is split up into the following activities:

Tip: For basic steps like adding a report to a Visual Studio project and viewing a report, please see the Basic Data Bound Reports walkthrough.

To complete the walkthrough, you must have access to the Northwind database.
A copy is located at C:\Program Files\GrapeCity\ActiveReports 6\Data\NWIND.MDB (on a 64-bit Windows operating system, a copy is located in C:\Program Files (x86)\GrapeCity\ActiveReports 6\Data\NWIND.MDB).

When you have completed this walkthrough, you will have an application that looks similar to the following.

To add controls to the form

  1. Resize the Windows form so that it is large enough to accommodate a number of controls.
  2. From the Visual Studio toolbox, drag the following controls onto the form and set the properties as indicated.

ShowForm controls

Control Location Dock Property Name Text
Panel Windows Form Left Panel1
Label Panel1 Top lblSelectFields Select Fields for Your Report
Checked ListBox Panel1 Fill clbFields
Button Panel1 Bottom btnGenRep Generate Report
CheckBox Panel1 Bottom chkGroup Group By Category ID
Viewer Windows Form Fill Viewer1

To generate a dataset for the form

  1. From the Project menu, select Add New Item.
  2. Select DataSet, rename the file NWINDDataSet.xsd and click the Add button.
  3. In the DataSet Designer that appears, click the Server Explorer link.
  4. In the Server Explorer, expand the node for your local copy of the Northwind database, then the Tables node, and drag the Products table onto the DataSet designer.
    Tip: If you do not see a copy of the Northwind database, click the Connect to Database icon and follow the prompts.
  5. In the design view of your Windows form, expand the Data section of the Visual Studio Toolbox and double-click DataSet to open the Add Dataset dialog.
  6. Under Typed dataset, select YourProjectName.NWINDDataSet and click OK to make the dataset available to your Windows form. nwindDataSet1 appears in the tray below the form.

To add code to create the report layout

  1. Right-click on rptRunTime and select View Code.
  2. Add code within the class declaration of the report to:
    • Create an array of fields
    • Create an option for whether to use groups
    • Set properties on the report sections
    • Add textboxes and labels to the report based on the array of fields
    • Handle exceptions

ShowTo write the code in Visual Basic.NET

The following example shows what the code for the method looks like.

Visual Basic.NET code. Paste INSIDE the class declaration of the report. Copy Code
Private m_arrayFields As ArrayList
Private m_useGroups As Boolean
'Create an array to hold the fields selected by the user
Public WriteOnly Property FieldsList() As ArrayList
   Set(ByVal Value As ArrayList)
       m_arrayFields = Value
   End Set
End Property
'Create a property to hold the user's grouping choice
Public WriteOnly Property UseGroups() As Boolean
   Set(ByVal Value As Boolean)
       m_useGroups = False
       m_useGroups = Value
   End Set
End Property
Private m_defaultHeight As Single = 0.2F
Private m_defaultWidth As Single = 4.0F
Private m_currentY As Single = 0.0F
'Set up report formatting and add fields based on user choices
Private Sub constructReport()
   Try
      Me.Detail1.CanGrow = True
      Me.Detail1.CanShrink = True
      Me.Detail1.KeepTogether = True
      If m_useGroups = True Then
         'If the user wants grouping, add a group header and footer and set the grouping field
          Me.Sections.InsertGroupHF()
          CType(Me.Sections("GroupHeader1"), GroupHeader).DataField = "CategoryID"
          Me.Sections("GroupHeader1").BackColor = System.Drawing.Color.Gray
          Me.Sections("GroupHeader1").CanGrow = True
          Me.Sections("GroupHeader1").CanShrink = True
          CType(Me.Sections("GroupHeader1"), GroupHeader).RepeatStyle = RepeatStyle.OnPageIncludeNoDetail
          'Add a textbox to display the group's category ID
          Dim txt As New TextBox
          txt.DataField = "CategoryID"
          txt.Location = New System.Drawing.PointF(0.0F, 0)
          txt.Width = 2.0F
          txt.Height = 0.3F
          txt.Style = "font-weight: bold; font-size: 16pt"
          Me.Sections("GroupHeader1").Controls.Add(txt)
      End If
      Dim i As Integer
      For i = 0 To m_arrayFields.Count - 1
          'For all fields selected by the user (except CategoryID) create a label and a textbox
          If m_arrayFields(i).ToString <> "CategoryID" Then
              Dim lbl As New Label
              'Set the label to display the name of the selected field
              lbl.Text = m_arrayFields(i) + ":"
              'Set the location of each label
              '(m_currentY gets the height of each control added on each iteration)
              lbl.Location() = New System.Drawing.PointF(0.0F, m_currentY)
              lbl.Width = 0.9F
              lbl.Height = m_defaultHeight
              Me.Detail1.Controls.Add(lbl)
              Dim txt As New TextBox
              'Set the textbox to display data
              txt.DataField = m_arrayFields(i)
              'Set the location of the textbox
              txt.Location = New System.Drawing.PointF(1.0F, m_currentY)
              txt.Width = m_defaultWidth
              txt.Height = m_defaultHeight
              Me.Detail1.Controls.Add(txt)
              'Set the textbox to use currency formatting if the field is UnitPrice
              If m_arrayFields(i) = "UnitPrice" Then
                 txt.OutputFormat = "$#.00"
              End If
              'Increment the vertical location by adding the height of the added controls
              m_currentY = m_currentY + m_defaultHeight
           End If
       Next
   Catch ex As Exception
       System.Windows.Forms.MessageBox.Show("Error in Report-constructReport: " + ex.Message, "Project Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error)
   End Try
End Sub

ShowTo write the code in C#

The following example shows what the code for the method looks like.

C# code. Paste INSIDE the class declaration of the report. Copy Code
private ArrayList m_arrayFields;
//Create an array to hold the fields selected by the user
public ArrayList FieldsList
{
   set{m_arrayFields = value;}
}
private bool m_useGroups = false;
//Create a property to hold the user's grouping choice
public bool UseGroups
{
   set{m_useGroups = value;}
}
float m_defaultHeight = .2f;
float m_defaultWidth = 4f;
float m_currentY = 0f;
//Set up report formatting and add fields based on user choices
private void constructReport()
{
   try
   {
      this.detail.CanGrow = true;
      this.detail.CanShrink = true;
      this.detail.KeepTogether = true;
      if(m_useGroups)
      {
        //If the user wants grouping, add a group header and footer and set the grouping field
        this.Sections.InsertGroupHF();
        ((GroupHeader)this.Sections["GroupHeader1"]).DataField = "CategoryID";
        this.Sections["GroupHeader1"].BackColor = System.Drawing.Color.Gray;
        this.Sections["GroupHeader1"].CanGrow = true;
        this.Sections["GroupHeader1"].CanShrink = true;
        ((GroupHeader)this.Sections["GroupHeader1"]).RepeatStyle = RepeatStyle.OnPageIncludeNoDetail;
        this.Sections["GroupFooter1"].Height = 0;
        //Add a textbox to display the group's category ID
        TextBox txt = new TextBox();
        txt.DataField = "CategoryID";
        txt.Location = new System.Drawing.PointF(0f,0);
        txt.Width =2f;
        txt.Height = .3f;
        txt.Style = "font-weight: bold; font-size: 16pt;";
        this.Sections["GroupHeader1"].Controls.Add(txt);
      }
      for(int i=0;i<m_arrayFields.Count;i++)
      {
        if(!m_useGroups || (m_useGroups && m_arrayFields[i].ToString() != "CategoryID"))
          //'For all fields selected by the user (except CategoryID) create a label and a textbox
          {
           Label lbl = new Label();
           //Set the label to display the name of the selected field
           lbl.Text = m_arrayFields[i].ToString() + ":";
           //Set the location of each label
           //(m_currentY gets the height of each control added on each iteration)
           lbl.Location = new System.Drawing.PointF(0f,m_currentY);
           lbl.Width =.9f;
           lbl.Height = m_defaultHeight;
           this.detail.Controls.Add(lbl);
           TextBox txt = new TextBox();
           //Set the textbox to display data
           txt.DataField = m_arrayFields[i].ToString();
           //Set the location of the textbox
           txt.Location = new System.Drawing.PointF(1f,m_currentY);
           txt.Width = m_defaultWidth;
           txt.Height = m_defaultHeight;
           this.detail.Controls.Add(txt);
          //Set the textbox to use currency formatting if the field is UnitPrice
          if (m_arrayFields[i].ToString().Equals("UnitPrice"))
          {
              txt.OutputFormat = "$#.00";
          }           
          //Increment the vertical location by adding the height of the added controls
           m_currentY = m_currentY + m_defaultHeight;
        }
      }
   }
   catch(Exception ex)
   {
      System.Windows.Forms.MessageBox.Show("Error in Report-constructReport: " + ex.Message,"Project Error",System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Error);
   }
}

To add code to fill the check list with fields and to launch the report

  1. Right-click the Windows Form and select View Code.
  2. Add code within the class declaration of the form to:
    • Fill the check list with fields
    • Launch the report

ShowTo write the code in Visual Basic.NET

The following example shows what the code for the method looks like.

Visual Basic.NET code. Paste INSIDE the class declaration of the form. Copy Code
Dim i As Integer
Dim c As Integer
Dim m_arrayField As New ArrayList()
Private Sub fillCheckBox()
   For i = 0 To Me.NwindDataSet1.Tables.Count - 1
      For c = 0 To Me.NwindDataSet1.Tables(i).Columns.Count - 1
        Me.clbFields.Items.Add(Me.NwindDataSet1.Tables(i).Columns(c).ColumnName)
      Next
   Next
End Sub
Private Sub launchReport()
   Dim rpt As New rptRunTime()
   Dim dataAdapter As New NWINDDataSetTableAdapters.ProductsTableAdapter
      Try
           rpt.FieldsList = m_arrayField
           rpt.UseGroups = chkGroup.Checked
           dataAdapter.Fill(NwindDataSet1.Products)
           rpt.DataSource = Me.NwindDataSet1.Products
           Viewer1.Document = rpt.Document
           rpt.Run()
        Catch ex As Exception
           System.Windows.Forms.MessageBox.Show(Me, "Error in launchReport: " + ex.Message, "Project Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
      End Try
End Sub

ShowTo write the code in C#

The following example shows what the code for the method looks like.

C# code. Paste INSIDE the class declaration of the form. Copy Code
ArrayList m_arrayField = new ArrayList();
private void fillCheckBox()
{
   for(int i = 0; i < this.nwindDataSet1.Tables.Count; i++)
   {
      for(int c = 0; c < this.nwindDataSet1.Tables[i].Columns.Count; c++)
      {
        this.clbFields.Items.Add(this.nwindDataSet1.Tables[i].Columns[c].ColumnName);
      }
   }
}
private void launchReport()
{
   try
   {
      rptRunTime rpt = new rptRunTime();
      rpt.FieldsList = m_arrayField;
      rpt.UseGroups = chkGroup.Checked;
      NWINDDataSetTableAdapters.ProductsTableAdapter dataAdapter = new NWINDDataSetTableAdapters.ProductsTableAdapter();
      dataAdapter.Fill(this.nwindDataSet1.Products);
      rpt.DataSource = this.nwindDataSet1.Products;
      this.Viewer1.Document = rpt.Document;
      rpt.Run();
   }
   catch(Exception ex)
   {
      MessageBox.Show(this,"Error in launchReport: " + ex.Message,"Project Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
   }
}

Adding code to alternate colors in the detail section

  1. Double-click in the detail section of rptRunTime. This creates an event-handling method for rptRunTime's Detail_Format event.
  2. Add code to the handler to alternate colors for a green bar report effect.

ShowTo write the code in Visual Basic.NET

The following example shows what the code for the method looks like.

Visual Basic.NET code. Paste JUST ABOVE the Detail Format event. Copy Code
Dim m_count As Integer
Visual Basic.NET code. Paste INSIDE the Detail Format event. Copy Code
If m_count Mod 2 = 0 Then
  Me.Detail1.BackColor = System.Drawing.Color.SlateGray
Else
  Me.Detail1.BackColor = System.Drawing.Color.Gainsboro
End If
m_count = m_count + 1

ShowTo write the code in C#

The following example shows what the code for the method looks like.

C# code. Paste JUST ABOVE the Detail Format event. Copy Code
int m_count;
C# code. Paste INSIDE the Detail Format event. Copy Code
if(m_count % 2 == 0)
{
  this.detail.BackColor = System.Drawing.Color.SlateGray;
}
else
{
  this.detail.BackColor = System.Drawing.Color.Gainsboro;
}
  m_count++;

Adding code to the ReportStart event to call the report layout code

  1. Double-click in the gray area below rptRunTime to create an event-handling method for rptRunTime's ReportStart event.
  2. Add code to call the constructReport method.

ShowTo write the code in Visual Basic.NET

The following example shows what the code for the method looks like.

Visual Basic.NET code. Paste INSIDE the ReportStart event. Copy Code
constructReport()

ShowTo write the code in C#

The following example shows what the code for the method looks like.

C# code. Paste INSIDE the ReportStart event. Copy Code
constructReport();

Adding code to the button's Click event to collect the selected values and launch the report

  1. Double-click btnGenRep to create an event-handling method for its Click event.
  2. Add code to the handler to collect the selected values and launch the report.

ShowTo write the code in Visual Basic.NET

The following example shows what the code for the method looks like.

Visual Basic.NET code. Paste INSIDE the button click event. Copy Code
Me.m_arrayField.Clear()
For i = 0 To Me.clbFields.CheckedItems.Count - 1
   m_arrayField.Add(Me.clbFields.CheckedItems(i).ToString)
Next
launchReport()

ShowTo write the code in C#

The following example shows what the code for the method looks like.

C# code. Paste INSIDE the button click event. Copy Code
this.m_arrayField.Clear();
for(int i = 0; i < this.clbFields.CheckedItems.Count; i++)
{
  m_arrayField.Add(this.clbFields.CheckedItems[i].ToString());
}
launchReport();

Adding code to enable the button when fields are selected

ShowTo write the code in Visual Basic.NET

  1. At the top left of the code view for the form, click the drop-down arrow and select clbFields.
  2. At the top right of the code window, click the drop-down arrow and select SelectedIndexChanged. This creates an event-handling method for the clbFields_SelectedIndexChanged event.
  3. Add code to the handler to enable the button when fields are selected.

The following example shows what the code for the method looks like.

Visual Basic.NET code. Paste INSIDE the SelectedIndexChanged event. Copy Code
If Me.clbFields.CheckedItems.Count < 0 Then
  Me.btnGenRep.Enabled = False
Else
  Me.btnGenRep.Enabled = True
End If

ShowTo write the code in C#

  1. On the form, click clbFields to select it.
  2. Click on the events icon in the Properties Window to display available events and double-click SelectedIndexChanged. This creates an event-handling method for the clbFields_SelectedIndexChanged event.
  3. Add code to the handler to enable the button when fields are selected.

The following example shows what the code for the method looks like.

C# code. Paste INSIDE the SelectedIndexChanged event. Copy Code
if(this.clbFields.CheckedItems.Count>0)
{
  this.btnGenRep.Enabled = true;
}
else
{
  this.btnGenRep.Enabled = false;
}

Adding code to the Form_Load event to call the fill check list code

  1. Double-click the title bar of the form. This creates an event-handling method for the Windows Form_Load event.
  2. Add code to the handler to call the fillCheckBox() method to populate clbFields with field values and to handle exceptions.

ShowTo write the code in Visual Basic.NET

The following example shows what the code for the method looks like.

Visual Basic.NET code. Paste INSIDE the Form Load event. Copy Code
Try
  fillCheckBox()
Catch ex As Exception
  System.Windows.Forms.MessageBox.Show(Me, "Error in Form1_Load: " + ex.Message, "Project Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

ShowTo write the code in C#

The following example shows what the code for the method looks like.

C# code. Paste INSIDE the Form Load event. Copy Code
try
{
  fillCheckBox();
}
catch(Exception ex)
{
  MessageBox.Show(this,"Error in Form1_Load: " + ex.Message,"Project Error", MessageBoxButtons.OK,MessageBoxIcon.Error);
}

See Also