C1Reports have not just made reporting easy; the customizations and features it offers have also added it in the list of user-friendly controls.

Generally, the reports are designed in the designer and then either the complete data is shown or the filtered records are fetched on the basis of the parameters passed by the users. What if the designing of the reports could also be done as per the user's discretion? That is, the users can decide which field to add in the report and which one to leave out.

This blog deals with the implementation of the same.

In order to allow the user to choose the fields that are to be added in the report, please note the following:

  1. The report should be created at runtime.

  2. The list of all the columns present in the data source of the report should be available at the time of report designing.


In our implementation we have used a couple of reports bound to different data sources. When the user selects any report the list of columns from the data source is shown in the listbox. The user can select which fields he wants to render on the report and add them in the second listbox.

Now, when the choices have been made, the selected columns are queried using the SQL query and set as the RecordSource of the report. The following is the code that is used to create the desired report:

 C1Report1.DataSource.RecordSource = ""
 Dim field_count As Integer = C1Report1.Fields.Count
 For c = 0 To field_count - 1
    C1Report1.Fields.RemoveAt(c)
 Next
 Dim col As String = ""
 Dim items = (From i In ListBox2.Items).ToArray()

 'Get the list of all selected columns
 For i = 0 To ListBox2.Items.Count - 1
    If ListBox2.Items.Count > 1 Then
       If i < ListBox2.Items.Count - 1 Then
           col = col & items(i).ToString & " , "
       Else
           col = col & items(i).ToString
       End If
    Else
       col = items(i).ToString
    End If
 Next

 'Setting the recordsource on the basis of the selected column names
 C1Report1.DataSource.RecordSource = "select " & col & " from " & dt.TableName

 C1Report1.Layout.Orientation = OrientationEnum.Portrait

 Dim f As Field
 With C1Report1.Sections(SectionTypeEnum.Header)
    .Height = 1440
    .Visible = True
    .BackColor = Color.FromArgb(200, 200, 200)
    f = .Fields.Add("FldTitle", "New Report", 0, 0, 8000, 1440)
    f.Font.Size = 24
    f.Font.Bold = True
    f.ForeColor = Color.FromArgb(0, 0, 100)
 End With

 l = 0
 With C1Report1.Sections(SectionTypeEnum.PageHeader)
    .Height = 300
    .Visible = True
    .CanGrow = False
    C1Report1.Font.Bold = True

    For i As Integer = 0 To ListBox2.Items.Count - 1
       If i = 0 Then
          f = .Fields.Add(ListBox2.Items(i).ToString, ListBox2.Items(i).ToString, 0, t, w, h)
       Else
          l = l + 1500
          f = .Fields.Add(ListBox2.Items(i).ToString, ListBox2.Items(i).ToString, l, t, w, h)
       End If
       f.Align = FieldAlignEnum.CenterMiddle
       f.CanGrow = True
    Next
 End With

 l = 0
 With C1Report1.Sections(SectionTypeEnum.Detail)
    .Height = 300
    .Visible = True
    .CanGrow = True
    C1Report1.Font.Bold = False

 For i As Integer = 0 To ListBox2.Items.Count - 1
    If i = 0 Then
       f = .Fields.Add("D" & ListBox2.Items(i).ToString, ListBox2.Items(i).ToString, 0, t, w, h)
    Else
       l = l + 1500
       f = .Fields.Add("D" & ListBox2.Items(i).ToString, ListBox2.Items(i).ToString, l, t, w, h)
    End If
       f.Align = FieldAlignEnum.CenterMiddle
       f.Calculated = True
       f.CanGrow = True
    Next

 End With
 C1PrintPreviewControl1.Document = C1Report1


Please refer to the attached Sample for the detailed implementation.

The following are the two outputs generated on the basis of the different fields selected by the user for the same report:

A. Shows the fields: ProductID, ProductName, CategoryID



B. Shows the fields: ProductId, QuantityPerUnit, UnitPrice, UnitsInStock