Here's a summary of the types of properties you can specify on custom controls that work well with IntelliSense and validation:
-
Attributes:
-
Simple datatypes (strings, enums, etc.)
<tag runat="server" simpleProp="simpleValue"/>
-
Any datatype with a [TypeConverter] that can convert 1) from a string to the desired type, and 2) from the type to InstanceDescriptor.
<tag runat="server" convertibleProp="convertibleValue"/>
-
Nested tags when the [ParseChildren(false)] attribute is on the class or no [ParseChildren] attribute exsits:
-
Nested tags when the [ParseChildren(true)] attribute is on the class and [PersistenceMode(PersistenceMode.Attribute)] is not specified on the property:
-
Simple datatypes and any datatype with a [TypeConverter], as above
<tag runat="server">
<simpleProp>simpleValue</simpleProp>
</tag>
-
Inner objects and controls with properties (Note: the getter must construct the object, which unfortunately makes it impossible to specify a subclass in its place within the .aspx markup; null can't be returned)
<tag runat="server">
<innerObjProp innerProp="innerVal" innerProp2="innerVal2" />
</tag>
-
Lists of controls when a List or List<T> getter is exposed (Note: an IList<T> getter doesn't work and you can't return null from the getter; the setter is never called)
<tag runat="server">
<listProp>simpleValue</listProp>
</tag>
-
A template containing 0+ controls via an ITemplate property; you need to instantiate the template in CreateChildControls() using template.InstantiateIn()
<tag runat="server">
<templateProp>Literal and <div runat="server">nested</div> content</templateProp>
</tag>