Implementing a Web Forms Data-Bound Control Designer
The main task of a data-bound control designer is to enable a control to access a different (sample) design-time data source when the control is in the designer. The .NET Framework provides an interface (IDataSourceProvider) that specifies the contract that enables access to a data source. A designer for a data-bound server control must implement the IDataSourceProvider interface and the other key steps described in the following procedure.
To implement a data-bound control designer
Note The following steps describe the specific implementation in the Web Forms Templated Data-Bound Control Designer Sample. This implementation can be applied to a control with a data source of type object that accepts an IEnumerable reference.
- Define a class that derives directly or indirectly from ControlDesigner and implements the IDataSourceProvider interface, as shown in the following code fragment.
Public Class DataboundControlDesigner Inherits ControlDesigner Implements IDataSourceProvider ... End Class [C#] public class DataboundControlDesigner : ControlDesigner, IDataSourceProvider {...}
- Expose a property (of type string) named DataSource that specifies a design-time data source. For an example of how to implement this property, see the Web Forms Templated Data-Bound Control Designer Sample. The DataSource property of the designer works on top of the DataBindings collection of the control.
- Override the GetDesignTimeHtml method and set the data source of the control (which is associated with your designer) to the design-time data source. For an example of how to override this method to replace the data source, see the Web Forms Templated Data-Bound Control Designer Sample.
- Override the PreFilterProperties method to replace (or shadow) the DataSource property on the control with the design-time DataSource property. The PreFilterProperties method belongs to the IDesignerFilter interface, which enables a designer to replace or create properties and events at design time. IDesignerFilter is implemented by ControlDesigner. For more information about property filtering, see Metadata Filtering. The following code fragment shows how you can override the PreFilterProperties method.
Protected Overrides Sub PreFilterProperties(properties As IDictionary) MyBase.PreFilterProperties(properties) Dim prop As PropertyDescriptor prop = CType(properties("DataSource"), PropertyDescriptor) Debug.Assert(( Not (prop Is Nothing))) prop = TypeDescriptor.CreateProperty(Me.GetType(), prop, _ New Attribute() {New TypeConverterAttribute(GetType(DataSourceConverter))}) properties("DataSource") = prop End Sub [C#] protected override void PreFilterProperties(IDictionary properties) { base.PreFilterProperties(properties); PropertyDescriptor prop; prop = (PropertyDescriptor)properties["DataSource"]; Debug.Assert(prop != null); prop = TypeDescriptor.CreateProperty(this.GetType(), prop, new Attribute[] { new TypeConverterAttribute(typeof(DataSourceConverter)) }); properties["DataSource"] = prop; }
- Implement the methods of the IDataSourceProvider interface. This interface has two methods — GetResolvedSelectedDataSource and GetSelectedDataSource. The following code example shows the implementation of these methods in the Web Forms Templated Data-Bound Control Designer Sample.
Function GetResolvedSelectedDataSource() As IEnumerable Implements IDataSourceProvider.GetResolvedSelectedDataSource Return CType(CType(Me, IDataSourceProvider).GetSelectedDataSource(), IEnumerable) End Function Function GetSelectedDataSource() As Object Implements IDataSourceProvider.GetSelectedDataSource Dim selectedDataSource As Object = Nothing Dim dataSource As String = Nothing Dim binding As DataBinding = DataBindings("DataSource") If Not (binding Is Nothing) Then dataSource = binding.Expression End If If Not (dataSource Is Nothing) Then Dim componentSite As ISite = Component.Site If Not (componentSite Is Nothing) Then Dim container As IContainer = CType(componentSite.GetService(GetType(IContainer)), IContainer) If Not (container Is Nothing) Then Dim comp As IComponent = container.Components(dataSource) If TypeOf comp Is IEnumerable Then selectedDataSource = comp End If End If End If End If Return selectedDataSource End Function [C#] IEnumerable IDataSourceProvider.GetResolvedSelectedDataSource() { return (IEnumerable)((IDataSourceProvider)this).GetSelectedDataSource(); } object IDataSourceProvider.GetSelectedDataSource() { object selectedDataSource = null; string dataSource = null; DataBinding binding = DataBindings["DataSource"]; if (binding != null) { dataSource = binding.Expression; } if (dataSource != null) { ISite componentSite = Component.Site; if (componentSite != null) { IContainer container = (IContainer)componentSite.GetService(typeof(IContainer)); if (container != null) { IComponent comp = container.Components[dataSource]; if (comp is IEnumerable) { selectedDataSource = comp; } } } } return selectedDataSource; }
For a complete sample that contains the preceding steps, see the Web Forms Templated Data-Bound Control Designer Sample.
See Also
Web Forms Templated Data-Bound Control Designer Sample | Implementing a Web Forms Template Editor | Custom Designers | Design-Time Support for Web Forms