Programming Microsoft ASP.NET 4 - Dino Esposito [277]
The former is set to the name of the public field on the data source that will render the text of displayed list items. The latter is set to the name of the field on the bound data source object that will render the unique value associated with each displayed list item.
On a new data-bound control, you need to define similar properties to specify any required mapping between data source fields and bindable control properties. All these properties are usually string properties stored in the view state; the name is arbitrary, but it generally follows the pattern DataXxxField, where Xxx indicates the role of the bindable control property.
Adding a Data Item Property
By design, the bound data source object must be an object that implements any of the following interfaces: IEnumerable (collections), IListSource (ADO.NET objects), or IDataSource (data source controls). Let’s suppose you bind a control to one row of a DataTable. Do you really need to persist the whole data row? If yes, what if the data row contains a couple of large binary large object (BLOB) fields?
The recommended approach entails that you extract a subset of information from the originally bound data source object and copy that to a control-specific data item object. This object is an instance of a custom class that typically has as many public properties as there are bindable properties on the control. For example, the DropDownList control has two bindable properties: Text and Value. Subsequently, the data item object—named ListItem—has two properties: Text and Value. (Naming is arbitrary, though.)
In a new data-bound control, you define a data item class that will be filled with any necessary information contained in the bound data source. This data item object must be persisted through the view state to guarantee that the control refreshes properly across postbacks. For performance reasons, the data item class must be able to serialize itself to the view state without resorting to the binary formatter. Put another way, it means that the data item class must implement IStateManager, just like style classes do.
Note
The data item class will be a collection of single data item classes if the data binding involves the association of a list of elements to a control.
Overriding the PerformDataBinding Method
The final key feature for a custom data-bound control is overriding the PerformDataBinding method. The method receives the contents of the bound data source object in the form of an enumerable object. As a control developer, you must read any required data from the source and cache it in the data item object.
Finally, you modify the rendering engine of the control to display bound data.
Note
Unless you need a data-bound control that behaves in a particular way (for example, a list control or a composite data-bound control), deriving your control from DataBoundControl is the most reasonable thing to do most of the time. If you need to start from a lower level, though, you can inherit from BaseDataBoundControl and override PerformSelect and ValidateDataSource. Needless to say, you might want to take this route only if you need to change the way a data source is validated, retrieved, or both.
The GaugeBar Control
Let’s apply all the steps outlined so far to a new version of the SimpleGaugeBar control, aptly named GaugeBar. The new control will still be a composite control, but it will inherit from DataBoundControl to gain standard data-binding capabilities.
public class GaugeBar : DataBoundControl
{
...
}
To be precise, ASP.NET also features a class that incorporates both composition and data binding. The name of the class is CompositeDataBoundControl.
Mapping Data Source Fields to Control Properties
The new GaugeBar control uses the same code as SimpleGaugeBar and extends it to define a couple of bindable properties—say, Value