# Binding to Collection Properties

## Environment

| Product           | Author                                                                          |
| ----------------- | ------------------------------------------------------------------------------- |
| Telerik Reporting | [Desislava Yordanova](https://www.telerik.com/blogs/author/desislava-yordanova) |

## Description

A common scenario is to set a [Data Item](https://www.telerik.com/products/reporting/documentation/designing-reports/connecting-to-data/data-items/overview)'s **DataSource** property to a custom Business object.

Depending on the underlying data structure [ObjectDataSource](https://www.telerik.com/products/reporting/documentation/designing-reports/connecting-to-data/data-source-components/objectdatasource-component/overview), [EntityDataSource](https://www.telerik.com/products/reporting/documentation/designing-reports/connecting-to-data/data-source-components/entitydatasource-component/overview), etc. components can be used to expose the properties of the Business object to the report. However, if the data schema is **not flat** and some of the properties represent child (nested) data collections, you may need to bind a report to the hierarchical data.

To use hierarchical data, you can take advantage of the [Bindings](https://www.telerik.com/products/reporting/documentation/designing-reports/connecting-to-data/expressions/using-expressions/bindings) functionality. It lets you bind declaratively the data item's [DataSource](https://www.telerik.com/products/reporting/documentation/api/telerik.reporting.dataitem#Telerik_Reporting_DataItem_DataSource) property to a given collection property from your business object and the data item will display all collection items.

This tutorial shows a sample approach how to create a hierarchical Report Table using a collection of business objects that contain a collection property.

## Solution

Consider the scenario illustrating a custom business object `Contact` having as a property a collection of `Phone` objects.

1. Create a **ClassLibrary** project with the following definition:

   ```C#
   public class ContactsCollection
   {
   	BindingList<Contact> _contacts;
   	public ContactsCollection()
   	{
   		_contacts = new BindingList<Contact>();
   		for (int i = 0; i < 5; i++)
   		{
   			BindingList<Phone> phones = new BindingList<Phone>();
   			for (int j = 0; j < 3; j++)
   			{
   				phones.Add(new Phone("Phone" + i + "." + j));
   			}
   			_contacts.Add(new Contact("Contact" + i, phones));
   		}
   	}
   	public BindingList<Contact> AllContacts { get { return _contacts; } }
   }

   public class Contact
   {
   	public Contact(string _name, BindingList<Phone> _phones)
   	{
   		this.Name = _name;
   		this.Phones = _phones;
   	}
   	public string Name { get; set; }
   	public BindingList<Phone> Phones { get; set; }
   }

   public class Phone
   {
   	public Phone(string _number)
   	{
   		this.Number = _number;
   	}
   	public string Number { get; set; }
   }
   ```

2. Build the project to ensure that **ContactsClassLibrary.dll** is produced in the **bin** folder.

3. [Extend the Report Designer to Recognize the Custom Assembly](https://www.telerik.com/products/reporting/documentation/designing-reports/report-designer-tools/desktop-designers/standalone-report-designer/configuration/extending-report-designer)

4. Create a brand new report and add an **ObjectDataSource** data item bound to the ContactsCollection.**AllContacts** property:

   ![Binding ObjectDataSource](https://www.telerik.com/products/reporting/documentation/assets/6dea286538a3fbe53d77f5b7aafe3907/binding-object-data-source.png)

5. Create a Table Report Item using the wizard and bind it to the defined **ObjectDataSource**:

   ![Table Wizard](https://www.telerik.com/products/reporting/documentation/assets/303088ce730bdb22164700ab0d7ffd8e/table-wizard.png)

6. Previewing the report at this state is expected to produce the following result:

   ![Initial Preview](https://www.telerik.com/products/reporting/documentation/assets/4586e09d97cd596805799b630b115354/initial-preview.png)

7. Select the **=Fields.Phones** TextBox and replace it with an empty Table item:

   ![Replace with Empty Table](https://www.telerik.com/products/reporting/documentation/assets/beb2192129d3b6f646942f5fa5d8862a/replace-with-empty-table.png)

8. Adjust the empty Table's **DataSource** via Bindings:

   ![Bind the Empty Table](https://www.telerik.com/products/reporting/documentation/assets/a5d6c922f04f14a5ca31922f24ce5d0f/bind-the-empty-table.png)

9. Select one of the generated TextBoxes in the empty Table and set its **Value** property to the desired property of the **Phone** class, e.g. "Number":

   ![Bind the Nested Property](https://www.telerik.com/products/reporting/documentation/assets/33fdd2203e0fac81aed5e911868b072c/bind-the-nested-property.png)

10. Preview the report and see the phones for each contact:

    ![Hierarchical Table](https://www.telerik.com/products/reporting/documentation/assets/ee5f4222508ee163201edb18fb20d99f/hierarchical-table.png)

## Notes

The expressions are evaluated only during the report processing. Thus, the data schema for the nested data item (Table) will not be available in the [Data Explorer](https://www.telerik.com/products/reporting/documentation/designing-reports/report-designer-tools/desktop-designers/tools/data-explorer) and the wizards.

You can use additional data source components bound to the nested business objects to help yourself with creating the report layout. After applying the required bindings, you may remove the helper object data source components.

The extra data sources may remain in the report definition to help with future changes in the report design. They won't affect report rendering, since the bindings will override them.

## See Also

* [Extending Report Designer to Recognize Custom Assemblies](https://www.telerik.com/products/reporting/documentation/designing-reports/report-designer-tools/desktop-designers/standalone-report-designer/configuration/extending-report-designer)
* [Bind to a BusinessObject](https://www.telerik.com/products/reporting/documentation/designing-reports/connecting-to-data/data-source-components/objectdatasource-component/bind-to-a-businessobject)
* [Bindings](https://www.telerik.com/products/reporting/documentation/designing-reports/connecting-to-data/expressions/using-expressions/bindings)
* [Data Binding Problems](https://www.telerik.com/products/reporting/documentation/knowledge-base/data-binding-problems)
* [How to use the ReportItem.DataObject property in expressions](https://www.telerik.com/products/reporting/documentation/designing-reports/connecting-to-data/data-items/how-to-use-the-reportitem.dataobject-property-in-expressions)
