Mercurial > pub > bltoolkit
diff Source/ComponentModel/CustomTypeDescriptorImpl.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/CustomTypeDescriptorImpl.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,229 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Reflection; + +using BLToolkit.Reflection; + +namespace BLToolkit.ComponentModel +{ + public class CustomTypeDescriptorImpl : ICustomTypeDescriptor + { + #region Constructors + + public CustomTypeDescriptorImpl() + { + _typeDescriptionProvider = CreateTypeDescriptionProvider(GetType()); + } + + public CustomTypeDescriptorImpl(Type type) + { + _typeDescriptionProvider = CreateTypeDescriptionProvider(type); + } + + public CustomTypeDescriptorImpl(ITypeDescriptionProvider typeDescriptionProvider) + { + _typeDescriptionProvider = typeDescriptionProvider; + } + + private readonly ITypeDescriptionProvider _typeDescriptionProvider; + + protected virtual ITypeDescriptionProvider CreateTypeDescriptionProvider(Type type) + { + return TypeAccessor.GetAccessor(type); + } + + #endregion + + #region ICustomTypeDescriptor Members + + AttributeCollection _attributes; + AttributeCollection ICustomTypeDescriptor.GetAttributes() + { + if (_attributes == null) + _attributes = _typeDescriptionProvider.GetAttributes(); + + return _attributes; + } + + string ICustomTypeDescriptor.GetClassName() + { + return _typeDescriptionProvider.ClassName; + } + + string ICustomTypeDescriptor.GetComponentName() + { + return _typeDescriptionProvider.ComponentName; + } + + TypeConverter _converter; + TypeConverter ICustomTypeDescriptor.GetConverter() + { + if (_converter == null) + { + TypeConverterAttribute attr = + _td.GetAttributes()[typeof(TypeConverterAttribute)] as TypeConverterAttribute; + + if (attr != null && !string.IsNullOrEmpty(attr.ConverterTypeName)) + { + Type type = GetTypeByName(attr.ConverterTypeName); + + if (type != null && typeof(TypeConverter).IsAssignableFrom(type)) + _converter = (TypeConverter)CreateInstance(type); + } + + if (_converter == null) + _converter = new TypeConverter(); + } + + return _converter; + } + + bool _readDefaultEvent; + EventDescriptor _defaultEvent; + EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() + { + if (_readDefaultEvent == false) + { + _readDefaultEvent = true; + + DefaultEventAttribute attr = + _td.GetAttributes()[typeof(DefaultEventAttribute)] as DefaultEventAttribute; + + if (attr != null && !string.IsNullOrEmpty(attr.Name)) + _defaultEvent = _typeDescriptionProvider.GetEvent(attr.Name); + } + + return _defaultEvent; + } + + bool _readDefaultProperty; + PropertyDescriptor _defaultProperty; + PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() + { + if (_readDefaultProperty == false) + { + _readDefaultProperty = true; + + DefaultPropertyAttribute attr = + _td.GetAttributes()[typeof(DefaultPropertyAttribute)] as DefaultPropertyAttribute; + + if (attr != null && !string.IsNullOrEmpty(attr.Name)) + _defaultProperty = _typeDescriptionProvider.GetProperty(attr.Name); + } + + return _defaultProperty; + } + + Hashtable _editors; + object ICustomTypeDescriptor.GetEditor(Type editorBaseType) + { + if (_editors == null) + _editors = new Hashtable(); + + object editor = _editors[editorBaseType]; + + if (editor == null) + { + if (_editors.Contains(editorBaseType)) + return null; + + foreach (Attribute attr in _td.GetAttributes()) + { + if (attr is EditorAttribute) + { + EditorAttribute ea = (EditorAttribute)attr; + + if (ea.EditorBaseTypeName != null && + ea.EditorTypeName != null && + editorBaseType == GetTypeByName(ea.EditorBaseTypeName)) + { + Type type = GetTypeByName(ea.EditorTypeName); + + if (type != null) + { + editor = CreateInstance(type); + break; + } + } + } + } + + _editors[editorBaseType] = editor; + } + + return editor; + } + + EventDescriptorCollection _events; + EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) + { + if (_events == null) + _events = _typeDescriptionProvider.GetEvents(); + + return _events; + } + + EventDescriptorCollection ICustomTypeDescriptor.GetEvents() + { + return _td.GetEvents(null); + } + + PropertyDescriptorCollection _properties; + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) + { + if (_properties == null) + _properties = _typeDescriptionProvider.GetProperties(); + + return _properties; + } + + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() + { + return _td.GetProperties(null); + } + + object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) + { + return this; + } + + #endregion + + #region Protected Members + + private Type GetTypeByName(string typeName) + { + if (string.IsNullOrEmpty(typeName)) + return null; + + Type type = Type.GetType(typeName); + + if (type != null) + return type; + + int idx = typeName.IndexOf(','); + + if (idx != -1) + typeName = typeName.Substring(0, idx); + + return _typeDescriptionProvider.OriginalType.Assembly.GetType(typeName); + } + + private object CreateInstance(Type type) + { + ConstructorInfo ci = type.GetConstructor(new Type[]{ typeof(Type) }); + + return ci != null? + Activator.CreateInstance(type, new object[] { _typeDescriptionProvider.OriginalType }): + Activator.CreateInstance(type); + } + + private ICustomTypeDescriptor _td + { + get { return this; } + } + + #endregion + } +}