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
+	}
+}