Business Logic Toolkit for .NET
www.bltoolkit.net
|  Home   |  Download   |  Documentation   |  Discussions   |  License   |

  Source.ComponentModel.CustomTypeDescriptorImpl.cs

 
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
    }
}
 
© 2010 www.bltoolkit.net
support@bltoolkit.net