using System; using System.Collections; using System.ComponentModel; using System.Drawing.Design; namespace Flobbster.Windows.Forms { public class PropertyBag : ICustomTypeDescriptor { [Serializable] public class PropertySpecCollection : IList, ICollection, IEnumerable { private ArrayList innerArray; public int Count { get { return innerArray.Count; } } public bool IsFixedSize { get { return false; } } public bool IsReadOnly { get { return false; } } public bool IsSynchronized { get { return false; } } object ICollection.SyncRoot { get { return null; } } public PropertySpec this[int index] { get { return (PropertySpec)innerArray[index]; } set { innerArray[index] = value; } } object IList.this[int index] { get { return this[index]; } set { this[index] = (PropertySpec)value; } } public PropertySpecCollection() { innerArray = new ArrayList(); } public int Add(PropertySpec value) { return innerArray.Add(value); } public void AddRange(PropertySpec[] array) { innerArray.AddRange(array); } public void Clear() { innerArray.Clear(); } public bool Contains(PropertySpec item) { return innerArray.Contains(item); } public bool Contains(string name) { foreach (PropertySpec item in innerArray) { if (item.Name == name) { return true; } } return false; } public void CopyTo(PropertySpec[] array) { innerArray.CopyTo(array); } public void CopyTo(PropertySpec[] array, int index) { innerArray.CopyTo(array, index); } public IEnumerator GetEnumerator() { return innerArray.GetEnumerator(); } public int IndexOf(PropertySpec value) { return innerArray.IndexOf(value); } public int IndexOf(string name) { int num = 0; foreach (PropertySpec item in innerArray) { if (item.Name == name) { return num; } num++; } return -1; } public void Insert(int index, PropertySpec value) { innerArray.Insert(index, value); } public void Remove(PropertySpec obj) { innerArray.Remove(obj); } public void Remove(string name) { int index = IndexOf(name); RemoveAt(index); } public void RemoveAt(int index) { innerArray.RemoveAt(index); } public PropertySpec[] ToArray() { return (PropertySpec[])innerArray.ToArray(typeof(PropertySpec)); } void ICollection.CopyTo(Array array, int index) { CopyTo((PropertySpec[])array, index); } int IList.Add(object value) { return Add((PropertySpec)value); } bool IList.Contains(object obj) { return Contains((PropertySpec)obj); } int IList.IndexOf(object obj) { return IndexOf((PropertySpec)obj); } void IList.Insert(int index, object value) { Insert(index, (PropertySpec)value); } void IList.Remove(object value) { Remove((PropertySpec)value); } } private class PropertySpecDescriptor : PropertyDescriptor { private PropertyBag bag; private PropertySpec item; public override Type ComponentType { get { return item.GetType(); } } public override bool IsReadOnly { get { return Attributes.Matches(ReadOnlyAttribute.Yes); } } public override Type PropertyType { get { return Type.GetType(item.TypeName); } } public PropertySpecDescriptor(PropertySpec item, PropertyBag bag, string name, Attribute[] attrs) : base(name, attrs) { this.bag = bag; this.item = item; } public override bool CanResetValue(object component) { if (item.DefaultValue == null) { return false; } return !GetValue(component).Equals(item.DefaultValue); } public override object GetValue(object component) { PropertySpecEventArgs propertySpecEventArgs = new PropertySpecEventArgs(item, null); bag.OnGetValue(propertySpecEventArgs); return propertySpecEventArgs.Value; } public override void ResetValue(object component) { SetValue(component, item.DefaultValue); } public override void SetValue(object component, object value) { PropertySpecEventArgs e = new PropertySpecEventArgs(item, value); bag.OnSetValue(e); } public override bool ShouldSerializeValue(object component) { object value = GetValue(component); if (item.DefaultValue == null && value == null) { return false; } return !value.Equals(item.DefaultValue); } } private string defaultProperty; private PropertySpecCollection properties; public string DefaultProperty { get { return defaultProperty; } set { defaultProperty = value; } } public PropertySpecCollection Properties { get { return properties; } } public event PropertySpecEventHandler GetValue; public event PropertySpecEventHandler SetValue; public PropertyBag() { defaultProperty = null; properties = new PropertySpecCollection(); } protected virtual void OnGetValue(PropertySpecEventArgs e) { if (this.GetValue != null) { this.GetValue(this, e); } } protected virtual void OnSetValue(PropertySpecEventArgs e) { if (this.SetValue != null) { this.SetValue(this, e); } } AttributeCollection ICustomTypeDescriptor.GetAttributes() { return TypeDescriptor.GetAttributes(this, true); } string ICustomTypeDescriptor.GetClassName() { return TypeDescriptor.GetClassName(this, true); } string ICustomTypeDescriptor.GetComponentName() { return TypeDescriptor.GetComponentName(this, true); } TypeConverter ICustomTypeDescriptor.GetConverter() { return TypeDescriptor.GetConverter(this, true); } EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); } PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { PropertySpec propertySpec = null; if (defaultProperty != null) { int index = properties.IndexOf(defaultProperty); propertySpec = properties[index]; } if (propertySpec != null) { return new PropertySpecDescriptor(propertySpec, this, propertySpec.Name, null); } return null; } object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); } EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return TypeDescriptor.GetEvents(this, true); } EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() { return ((ICustomTypeDescriptor)this).GetProperties(new Attribute[0]); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { ArrayList arrayList = new ArrayList(); foreach (PropertySpec property in properties) { ArrayList arrayList2 = new ArrayList(); if (property.Category != null) { arrayList2.Add(new CategoryAttribute(property.Category)); } if (property.Description != null) { arrayList2.Add(new DescriptionAttribute(property.Description)); } if (property.EditorTypeName != null) { arrayList2.Add(new EditorAttribute(property.EditorTypeName, typeof(UITypeEditor))); } if (property.ConverterTypeName != null) { arrayList2.Add(new TypeConverterAttribute(property.ConverterTypeName)); } if (property.Attributes != null) { arrayList2.AddRange(property.Attributes); } Attribute[] attrs = (Attribute[])arrayList2.ToArray(typeof(Attribute)); PropertySpecDescriptor value = new PropertySpecDescriptor(property, this, property.Name, attrs); arrayList.Add(value); } PropertyDescriptor[] array = (PropertyDescriptor[])arrayList.ToArray(typeof(PropertyDescriptor)); return new PropertyDescriptorCollection(array); } object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { return this; } } }