Just like its earlier versions, one of the coolest features of ActiveReports 7 is the End User Designer which is shipped with its professional edition. It can be embedded into your application and allow the end users to edit reports at their end.  It incorporates all the functionality offered by the Visual Studio designer of ActiveReports, and provides excellent customization options.

Since this report designer mainly targets the end users, developers  might wish  to customize the data source options which they would like to present to their end users. In this blog article, I would like to present one such customization which can be integrated into the End User Designer. As of now, ActiveReports offers Page Based and Section Based report layouts; and this blog mainly focuses on the Section Based reports.

This blog implementation handles the data source button to suppress the default data source dialog box and replace it with a DataGridView to create a customized data source for the reports.  Let us see how the custom data source dialog looks like:






So the new data source dialog contains a TextBox to input the field name and the second TextBox to specify its Type. Once the field name and its type is set, Add Field button can be used to add that field as a column name in the DataGridView. Once all the required columns are added, user can enter field values in the DatGridView. Clicking the OK button, assigns the Grid data as the report's data source and all the fields added in the DataGridView are listed under the bound fields section in the report explorer.







These newly defined bound fields can be simply dragged and dropped onto the designer and the report can be previewed to see the values added under different field names. Here is the output:



So far we have seen how the changes actually appear; but now lets quickly take a look at the code to make all these modifications.  In this code implementation, the most important thing is the event which is used to suppress the default data source dialog box. ActiveReports designer provides DataSourceIconClick event which fires when the data source icon is clicked on the designer.

Following code can be used to open the custom data source dialog:


private void reportdesigner_DataSourceIconClick(object sender, DataSourceIconClickEventArgs e)
{
DataSourceForm dsForm = new DataSourceForm();
if (dsForm.ShowDialog() == DialogResult.OK)
{
((SectionReport)reportdesigner.Report).DataSource = dsForm.DataSource;
e.Cancel = true;
}
else
e.Cancel = false;
}


As you must have noticed in the above code, we are invoking another form, which acts as the custom data source dialog box. Code block below describes, how this custom dialog box provides the option to populate the DataGridView and use it as the report's data source:


public partial class DataSourceForm : Form
{
public DataTable DataSource { get; set; }
private DataTable _dsTable=new DataTable();
private Dictionary<string, Type> AllDataTypes = new Dictionary<string, Type>();

public DataSourceForm()
{
InitializeComponent();
GetAllDataTypes();
cmbDataType.SelectedIndex = 0;
}

void GetAllDataTypes()
{
AllDataTypes = new Dictionary<string, Type>();
AllDataTypes.Add("Int", typeof(int));
AllDataTypes.Add("String", typeof(string));
AllDataTypes.Add("DateTime", typeof(DateTime));
AllDataTypes.Add("Decimal", typeof(decimal));
AllDataTypes.Add("Bool", typeof(bool));
}

private void btnAddField_Click(object sender, EventArgs e)
{
if (txtFieldName.Text == "")
{
MessageBox.Show("Enter a field name");
return;
}
try
{
_dsTable.Columns.Add(txtFieldName.Text, AllDataTypes[cmbDataType.SelectedItem.ToString()]);
dsGridView.DataSource = _dsTable;
txtFieldName.Text = "";
cmbDataType.SelectedIndex = 0;
}
catch(DataException ex)
{
MessageBox.Show(ex.Message);
}
}

private void btnOk_Click(object sender, EventArgs e)
{
_dsTable.AcceptChanges();
DataSource = _dsTable;
this.DialogResult = DialogResult.OK;
this.Close();
}

private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}


Above code provides an option to enter the field name using a TextBox. DataType for this field can be defined using the ComboBox populated with all the desired data types using the function GetAllDataTypes(). Once the user adds a field and specify its data type, it is added as a column into a datatable and finally this datatable is used as the datasource for the DataGridView.

Refer to the attached samples for complete implementation.
Download Sample C#
Download Sample VB.NET