Mercurial > pub > bltoolkit
diff Source/ComponentModel/TypeDescriptorExtender.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/ComponentModel/TypeDescriptorExtender.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,232 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Reflection; + +using BLToolkit.Reflection; + +namespace BLToolkit.ComponentModel +{ + public abstract class TypeDescriptorExtender : ICustomTypeDescriptor, ITypeDescriptionProvider + { + #region Constructors + + protected TypeDescriptorExtender(Type baseType) + { + if (baseType == null) + throw new ArgumentNullException("baseType"); + + _baseObject = TypeAccessor.CreateInstanceEx(baseType); + } + + protected TypeDescriptorExtender(object baseObject) + { + if (baseObject == null) + throw new ArgumentNullException("baseObject"); + + _baseObject = baseObject; + } + + #endregion + + #region Public Members + + private readonly object _baseObject; + public object BaseObject + { + get { return _baseObject; } + } + + #endregion + + #region Protected Members + + private static readonly Hashtable _hashDescriptors = new Hashtable(); + + [NonSerialized] + private ICustomTypeDescriptor _typeDescriptor; + private ICustomTypeDescriptor TypeDescriptor + { + get + { + if (_typeDescriptor == null) + { + Type key1 = GetType(); + Type key2 = _baseObject.GetType(); + + Hashtable tbl = (Hashtable)_hashDescriptors[key1]; + + if (tbl == null) + _hashDescriptors[key1] = tbl = new Hashtable(); + + _typeDescriptor = (ICustomTypeDescriptor)tbl[key2]; + + if (_typeDescriptor == null) + tbl[key2] = _typeDescriptor = CreateTypeDescriptor(); + } + + return _typeDescriptor; + } + } + + private ICustomTypeDescriptor CreateTypeDescriptor() + { + return new CustomTypeDescriptorImpl(this); + } + + #endregion + + #region ICustomTypeDescriptor Members + + AttributeCollection ICustomTypeDescriptor.GetAttributes() + { + return TypeDescriptor.GetAttributes(); + } + + string ICustomTypeDescriptor.GetClassName() + { + return TypeDescriptor.GetClassName(); + } + + string ICustomTypeDescriptor.GetComponentName() + { + return TypeDescriptor.GetComponentName(); + } + + TypeConverter ICustomTypeDescriptor.GetConverter() + { + return TypeDescriptor.GetConverter(); + } + + EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() + { + return TypeDescriptor.GetDefaultEvent(); + } + + PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() + { + return TypeDescriptor.GetDefaultProperty(); + } + + object ICustomTypeDescriptor.GetEditor(Type editorBaseType) + { + return TypeDescriptor.GetEditor(editorBaseType); + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) + { + return TypeDescriptor.GetEvents(attributes); + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents() + { + return TypeDescriptor.GetEvents(); + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) + { + return TypeDescriptor.GetProperties(attributes); + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() + { + return TypeDescriptor.GetProperties(); + } + + object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) + { + return TypeDescriptor.GetPropertyOwner(pd); + } + + #endregion + + #region ITypeDescriptionProvider Members + + [NonSerialized] + private ICustomTypeDescriptor _baseTypeDescriptor; + private ICustomTypeDescriptor BaseTypeDescriptor + { + get + { + if (_baseTypeDescriptor == null) + { + _baseTypeDescriptor = _baseObject as ICustomTypeDescriptor ?? + new CustomTypeDescriptorImpl(_baseObject.GetType()); + } + + return _baseTypeDescriptor; + } + } + + [NonSerialized] + private ITypeDescriptionProvider _provider; + private ITypeDescriptionProvider Provider + { + get + { + if (_provider == null) + _provider = TypeAccessor.GetAccessor(GetType()); + + return _provider; + } + } + + Type ITypeDescriptionProvider.OriginalType { get { return GetType(); } } + string ITypeDescriptionProvider.ClassName { get { return GetType().Name; } } + string ITypeDescriptionProvider.ComponentName { get { return GetType().Name; } } + + EventDescriptor ITypeDescriptionProvider.GetEvent(string name) + { + EventInfo ei = GetType().GetEvent(name); + + return ei != null ? Provider.GetEvent(name) : BaseTypeDescriptor.GetEvents()[name]; + } + + PropertyDescriptor ITypeDescriptionProvider.GetProperty(string name) + { + PropertyDescriptor pd = Provider.GetProperty(name); + + return pd ?? BaseTypeDescriptor.GetProperties()[name]; + } + + AttributeCollection ITypeDescriptionProvider.GetAttributes() + { + AttributeCollection col1 = Provider.GetAttributes(); + AttributeCollection col2 = BaseTypeDescriptor.GetAttributes(); + + Attribute[] attrs = new Attribute[col1.Count + col2.Count]; + + for (int i = 0; i < col1.Count; i++) + attrs[i] = col1[i]; + + for (int i = 0; i < col2.Count; i++) + attrs[col1.Count + i] = col2[i]; + + return new AttributeCollection(attrs); + } + + EventDescriptorCollection ITypeDescriptionProvider.GetEvents() + { + EventDescriptorCollection col1 = Provider.GetEvents(); + EventDescriptorCollection col2 = BaseTypeDescriptor.GetEvents(); + + EventDescriptorCollection col = new EventDescriptorCollection(new EventDescriptor[0]); + + foreach (EventDescriptor ed in col1) + col.Add(ed); + + foreach (EventDescriptor ed in col2) + if (col.Find(ed.Name, false) == null) + col.Add(ed); + + return col; + } + + PropertyDescriptorCollection ITypeDescriptionProvider.GetProperties() + { + throw new Exception("The method or operation is not implemented."); + } + + #endregion + } +}