using System; using System.ComponentModel; using System.Collections; namespace ServiceConfigurator { /// /// Modified class from the CustomClass originally created by Venu Madhav. /// Venu's DataTable and DataColumn objects have been removed and variables and /// class names have been renamed. The derived DynamicProperty class below now contains /// the property data. This is a simpler implementation becuase the backing store for /// the property data is the XML Config file - no need for another set of objects to hold /// the data before it gets written back to the config file (although actually holding the /// property data in the PropertyDescriptor class is probably a little unorthodox). /// CustomClass implements ICustomTypeDescriptor and derives ExpandableObjectConverter. /// This class can be instantiated and properties to this class can /// be added dynamically using AddProperty(string propName, object propValue, string propDesc, /// string propCat, System.Type propType, bool isReadOnly, bool isExpandable). /// [TypeConverter(typeof(ExpandableObjectConverter))] public partial class CustomClass : Component, ICustomTypeDescriptor { //Private members private PropertyDescriptorCollection propertyCollection; //Max length will be used help control the layout of the Windows Form and PropertyGrid //or the table of controls in an ASP.Net page. The Form or Webpage layout will be adjusted //dynamically depending on length of these values. private int _maxLength; public int MaxLength { get { return _maxLength; } set { if (value > _maxLength) _maxLength = value; } } /// /// Constructor of CustomClass which initializes the new PropertyDescriptorCollection. /// public CustomClass() { propertyCollection = new PropertyDescriptorCollection(new PropertyDescriptor[] { }); } /// /// Adds a property into the CustomClass. /// /// Name of the property that needs to be added. /// Value of the property that needs to be added. /// Description of the property that needs to be added. /// The category to display this property in. /// Sets the property value to readonly in the property grid. /// Tells the property grid that this property is expandable. /// DataType of the property that needs to be added. public void AddProperty(string propName, object propValue, string propDesc, string propCat, System.Type propType, bool isReadOnly, bool isExpandable) { DynamicProperty p = new DynamicProperty(propName, propValue, propDesc, propCat, propType, isReadOnly, isExpandable); propertyCollection.Add(p); //Set our layout helper value. this.MaxLength = propName.Length; this.MaxLength = propValue.ToString().Length; } //Indexer for this class - returns a DynamicProperty by index position. public DynamicProperty this[int index] { get { return (DynamicProperty)propertyCollection[index]; } } //Overloaded Indexer for this class - returns a DynamicProperty by name. public DynamicProperty this[string name] { get { return (DynamicProperty)propertyCollection[name]; } } /// /// /// /// public string GetClassName() { return (TypeDescriptor.GetClassName(this, true)); } /// /// /// /// public AttributeCollection GetAttributes() { return (TypeDescriptor.GetAttributes(this, true)); } /// /// /// /// public string GetComponentName() { return (TypeDescriptor.GetComponentName(this, true)); } /// /// /// /// public TypeConverter GetConverter() { return (TypeDescriptor.GetConverter(this, true)); } /// /// /// /// public EventDescriptor GetDefaultEvent() { return (TypeDescriptor.GetDefaultEvent(this, true)); } /// /// /// /// public PropertyDescriptor GetDefaultProperty() { PropertyDescriptorCollection props = GetAllProperties(); if (props.Count > 0) return (props[0]); else return (null); } /// /// /// /// /// public object GetEditor(Type editorBaseType) { return (TypeDescriptor.GetEditor(this, editorBaseType, true)); } /// /// /// /// /// public EventDescriptorCollection GetEvents(Attribute[] attributes) { return (TypeDescriptor.GetEvents(this, attributes, true)); } /// /// /// /// public EventDescriptorCollection GetEvents() { return (TypeDescriptor.GetEvents(this, true)); } /// /// /// /// /// public PropertyDescriptorCollection GetProperties(Attribute[] attributes) { return (GetAllProperties()); } /// /// /// /// public PropertyDescriptorCollection GetProperties() { return (GetAllProperties()); } /// /// /// /// /// public object GetPropertyOwner(PropertyDescriptor pd) { return (this); } /// /// Helper method to return the PropertyDescriptorCollection or our Dynamic Properties /// /// /// private PropertyDescriptorCollection GetAllProperties() { return propertyCollection; } /// /// This is the Property class this will be dynamically added to the class at runtime. /// These classes are returned in the PropertyDescriptorCollection of the GetAllProperties /// method of the custom class. /// /// /// public class DynamicProperty : PropertyDescriptor { private string propName; private object propValue; private string propDescription; private string propCategory; private Type propType; private bool isReadOnly; private bool isExpandable; public DynamicProperty(string pName, object pValue, string pDesc, string pCat, Type pType, bool readOnly, bool expandable) : base(pName, new Attribute[] { }) { propName = pName; propValue = pValue; propDescription = pDesc; propCategory = pCat; propType = pType; isReadOnly = readOnly; isExpandable = expandable; } public override System.Type ComponentType { get { return null; } } public override string Category { get { return propCategory; } } public override bool IsReadOnly { get { return isReadOnly; } } public override System.Type PropertyType { get { return propType; } } public override bool CanResetValue(object component) { return true; } public override object GetValue(object component) { return propValue; } public override void SetValue(object component, object value) { propValue = value; } public override void ResetValue(object component) { propValue = null; } public override bool ShouldSerializeValue(object component) { return false; } public override string Description { get { return propDescription; } } } } }