340 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			340 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
#if FRAMEWORK20
 | 
						|
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Text;
 | 
						|
using System.ComponentModel;
 | 
						|
using DevComponents.AdvTree;
 | 
						|
using System.Collections;
 | 
						|
 | 
						|
namespace DevComponents.DotNetBar
 | 
						|
{
 | 
						|
    internal class PropertyParser
 | 
						|
    {
 | 
						|
        private const string STR_Misc = "Misc.";
 | 
						|
 | 
						|
        #region Constructors
 | 
						|
        private object _SelectedObject = null;
 | 
						|
        private object[] _SelectedObjects = null;
 | 
						|
        private TypeConverter _Converter = null;
 | 
						|
        private Attribute[] _AttributeFilter = null;
 | 
						|
        private PropertyNodeFactory _PropertyNodeFactory = null;
 | 
						|
        private List<string> _IgnoredProperties = null;
 | 
						|
        private List<string> _IgnoredCategories = null;
 | 
						|
        private IPropertyGridLocalizer _Localizer = null;
 | 
						|
        private PropertySettingsCollection _PropertySettings = null;
 | 
						|
        private ITypeDescriptorContext _TypeDescriptorContext = null;
 | 
						|
        /// <summary>
 | 
						|
        /// Initializes a new instance of the PropertyParser class.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="selectedObject"></param>
 | 
						|
        public PropertyParser(object selectedObject,
 | 
						|
            Attribute[] attributeFilter,
 | 
						|
            PropertyNodeFactory nodeFactory,
 | 
						|
            List<string> ignoredProperties,
 | 
						|
            List<string> ignoredCategories,
 | 
						|
            IPropertyGridLocalizer localizer,
 | 
						|
            PropertySettingsCollection propertySettings)
 | 
						|
        {
 | 
						|
            _SelectedObject = selectedObject;
 | 
						|
            _AttributeFilter = attributeFilter;
 | 
						|
            _PropertyNodeFactory = nodeFactory;
 | 
						|
            _IgnoredProperties = ignoredProperties;
 | 
						|
            _IgnoredCategories = ignoredCategories;
 | 
						|
            _Localizer = localizer;
 | 
						|
            _PropertySettings = propertySettings;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Initializes a new instance of the PropertyParser class.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="selectedObject"></param>
 | 
						|
        public PropertyParser(
 | 
						|
            ITypeDescriptorContext context, 
 | 
						|
            object selectedObject,
 | 
						|
            Attribute[] attributeFilter,
 | 
						|
            PropertyNodeFactory nodeFactory,
 | 
						|
            List<string> ignoredProperties,
 | 
						|
            List<string> ignoredCategories,
 | 
						|
            IPropertyGridLocalizer localizer,
 | 
						|
            PropertySettingsCollection propertySettings)
 | 
						|
        {
 | 
						|
            _TypeDescriptorContext = context;
 | 
						|
            _SelectedObject = selectedObject;
 | 
						|
            _AttributeFilter = attributeFilter;
 | 
						|
            _PropertyNodeFactory = nodeFactory;
 | 
						|
            _IgnoredProperties = ignoredProperties;
 | 
						|
            _IgnoredCategories = ignoredCategories;
 | 
						|
            _Localizer = localizer;
 | 
						|
            _PropertySettings = propertySettings;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Initializes a new instance of the PropertyParser class.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="selectedObject"></param>
 | 
						|
        public PropertyParser(object[] selectedObjects,
 | 
						|
            Attribute[] attributeFilter,
 | 
						|
            PropertyNodeFactory nodeFactory,
 | 
						|
            List<string> ignoredProperties,
 | 
						|
            List<string> ignoredCategories,
 | 
						|
            IPropertyGridLocalizer localizer,
 | 
						|
            PropertySettingsCollection propertySettings)
 | 
						|
        {
 | 
						|
            _SelectedObjects = selectedObjects;
 | 
						|
            _AttributeFilter = attributeFilter;
 | 
						|
            _PropertyNodeFactory = nodeFactory;
 | 
						|
            _IgnoredProperties = ignoredProperties;
 | 
						|
            _IgnoredCategories = ignoredCategories;
 | 
						|
            _Localizer = localizer;
 | 
						|
            _PropertySettings = propertySettings;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Initializes a new instance of the PropertyParser class.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="selectedObject"></param>
 | 
						|
        public PropertyParser(
 | 
						|
            ITypeDescriptorContext context,
 | 
						|
            object[] selectedObjects,
 | 
						|
            Attribute[] attributeFilter,
 | 
						|
            PropertyNodeFactory nodeFactory,
 | 
						|
            List<string> ignoredProperties,
 | 
						|
            List<string> ignoredCategories,
 | 
						|
            IPropertyGridLocalizer localizer,
 | 
						|
            PropertySettingsCollection propertySettings)
 | 
						|
        {
 | 
						|
            _TypeDescriptorContext = context;
 | 
						|
            _SelectedObjects = selectedObjects;
 | 
						|
            _AttributeFilter = attributeFilter;
 | 
						|
            _PropertyNodeFactory = nodeFactory;
 | 
						|
            _IgnoredProperties = ignoredProperties;
 | 
						|
            _IgnoredCategories = ignoredCategories;
 | 
						|
            _Localizer = localizer;
 | 
						|
            _PropertySettings = propertySettings;
 | 
						|
        }
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Internal Implementation
 | 
						|
        internal void Parse(NodeCollection nodeCollection, ePropertySort propertySort, SuperTooltip helpTooltip)
 | 
						|
        {
 | 
						|
            PropertyDescriptorCollection propertyCollection = GetProperties();
 | 
						|
            bool hasIgnoredProperties = _IgnoredProperties.Count > 0;
 | 
						|
            bool hasIgnoredCategories = _IgnoredCategories.Count > 0;
 | 
						|
 | 
						|
            if (propertySort == ePropertySort.Categorized || propertySort == ePropertySort.CategorizedAlphabetical)
 | 
						|
            {
 | 
						|
                Dictionary<string, Node> table = new Dictionary<string, Node>();
 | 
						|
                foreach (PropertyDescriptor item in propertyCollection)
 | 
						|
                {
 | 
						|
                    if (item == null || hasIgnoredProperties && _IgnoredProperties.Contains(item.Name)) continue;
 | 
						|
 | 
						|
                    string category = GetCategory(item);
 | 
						|
                    PropertySettings settings = _PropertySettings[item, item.Name];
 | 
						|
                    if (settings != null && settings.Category != null)
 | 
						|
                        category = settings.Category;
 | 
						|
                        
 | 
						|
                    if (hasIgnoredCategories && !string.IsNullOrEmpty(category) && _IgnoredCategories.Contains(category)) continue;
 | 
						|
 | 
						|
                    Node categoryNode = null;
 | 
						|
                    if (!table.TryGetValue(category, out categoryNode))
 | 
						|
                    {
 | 
						|
                        categoryNode = _PropertyNodeFactory.CreateCategoryNode(category, _Localizer);
 | 
						|
                        nodeCollection.Add(categoryNode);
 | 
						|
                        table.Add(category, categoryNode);
 | 
						|
                    }
 | 
						|
                    PropertyNode node = _PropertyNodeFactory.CreatePropertyNode(item, _SelectedObject ?? _SelectedObjects, _Localizer, settings, _SelectedObjects != null);
 | 
						|
                    categoryNode.Nodes.Add(node);
 | 
						|
                    node.OnLoaded();
 | 
						|
                    if (_HelpType == ePropertyGridHelpType.SuperTooltip && helpTooltip != null)
 | 
						|
                        node.SetHelpTooltip(helpTooltip);
 | 
						|
                    node.UpdateDisplayedValue();
 | 
						|
                }
 | 
						|
 | 
						|
                if (propertySort == ePropertySort.CategorizedAlphabetical)
 | 
						|
                {
 | 
						|
                    foreach (Node item in table.Values)
 | 
						|
                    {
 | 
						|
                        item.Nodes.Sort();
 | 
						|
                    }
 | 
						|
 | 
						|
                    nodeCollection.Sort();
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                foreach (PropertyDescriptor item in propertyCollection)
 | 
						|
                {
 | 
						|
                    if (item == null || _IgnoredProperties.Contains(item.Name)) continue;
 | 
						|
 | 
						|
                    PropertyNode node = _PropertyNodeFactory.CreatePropertyNode(item, _SelectedObject ?? _SelectedObjects, _Localizer, _PropertySettings, _SelectedObjects != null);
 | 
						|
                    nodeCollection.Add(node);
 | 
						|
                    node.OnLoaded();
 | 
						|
                    if (_HelpType == ePropertyGridHelpType.SuperTooltip && helpTooltip != null)
 | 
						|
                        node.SetHelpTooltip(helpTooltip);
 | 
						|
                    node.UpdateDisplayedValue();
 | 
						|
                }
 | 
						|
                if (propertySort == ePropertySort.Alphabetical)
 | 
						|
                    nodeCollection.Sort();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        internal static bool GetReadOnlyAttribute(PropertyDescriptor item, object instance)
 | 
						|
        {
 | 
						|
            bool readOnly = TypeDescriptor.GetAttributes(instance).Contains(InheritanceAttribute.InheritedReadOnly);
 | 
						|
            // if (item.Attributes[typeof(ReadOnlyAttribute)].Equals(ReadOnlyAttribute.Yes))
 | 
						|
            if (TypeDescriptor.GetAttributes(instance).Contains(ReadOnlyAttribute.Yes))
 | 
						|
            {
 | 
						|
                readOnly |= true;
 | 
						|
            }
 | 
						|
            //if(_Converter!=null && _Converter)
 | 
						|
            
 | 
						|
            ReadOnlyAttribute readOnlyAttribute = item.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;
 | 
						|
            if (!readOnly && readOnlyAttribute != null && readOnlyAttribute.IsReadOnly && !readOnlyAttribute.IsDefaultAttribute())
 | 
						|
                readOnly |= true;
 | 
						|
 | 
						|
            if (!readOnly)
 | 
						|
            {
 | 
						|
                readOnly = item.IsReadOnly;
 | 
						|
            }
 | 
						|
            //if (item.Attributes[typeof(ImmutableObjectAttribute)].Equals(ImmutableObjectAttribute.Yes))
 | 
						|
            //    readOnly |= true;
 | 
						|
 | 
						|
            return readOnly; // item.IsReadOnly;
 | 
						|
        }
 | 
						|
 | 
						|
        private static CategoryAttribute _CategoryAttribute = new CategoryAttribute();
 | 
						|
        private string GetCategory(PropertyDescriptor item)
 | 
						|
        {
 | 
						|
            string s = item.Category;
 | 
						|
            if (!string.IsNullOrEmpty(s)) return s;
 | 
						|
            
 | 
						|
            CategoryAttribute cat = item.Attributes[_CategoryAttribute.GetType()] as CategoryAttribute;
 | 
						|
            if (cat != null && !string.IsNullOrEmpty(cat.Category)) return cat.Category;
 | 
						|
            
 | 
						|
            return STR_Misc;
 | 
						|
        }
 | 
						|
 | 
						|
        private TypeConverter GetConverter(object component)
 | 
						|
        {
 | 
						|
            if (_Converter != null && _SelectedObject != null) return _Converter;
 | 
						|
 | 
						|
            TypeConverter converter = TypeDescriptor.GetConverter(component);
 | 
						|
            if(converter.GetPropertiesSupported())
 | 
						|
                return converter;
 | 
						|
            return null;
 | 
						|
        }
 | 
						|
        private PropertyDescriptorCollection GetProperties()
 | 
						|
        {
 | 
						|
            Attribute[] attributes = _AttributeFilter;
 | 
						|
 | 
						|
            if (_SelectedObject != null)
 | 
						|
            {
 | 
						|
                object component = _SelectedObject;
 | 
						|
                return GetProperties(_TypeDescriptorContext, attributes, component, GetConverter(component));
 | 
						|
            }
 | 
						|
 | 
						|
            int selectedObjectsCount = _SelectedObjects.Length;
 | 
						|
            List<PropertyDescriptor> mergedProperties = new List<PropertyDescriptor>();
 | 
						|
 | 
						|
            List<PropertyDescriptorCollection> allProperties = new List<PropertyDescriptorCollection>(selectedObjectsCount);
 | 
						|
            foreach (object selectedObject in _SelectedObjects)
 | 
						|
            {
 | 
						|
                allProperties.Add(GetProperties(_TypeDescriptorContext, attributes, selectedObject, GetConverter(selectedObject)));
 | 
						|
            }
 | 
						|
 | 
						|
            PropertyDescriptorCollection col1 = allProperties[0];
 | 
						|
 | 
						|
            for (int i = 0; i < col1.Count; i++)
 | 
						|
            {
 | 
						|
                PropertyDescriptor propDesc = col1[i];
 | 
						|
                bool mergable = propDesc.Attributes[typeof(MergablePropertyAttribute)].IsDefaultAttribute();
 | 
						|
                if (!mergable) continue;
 | 
						|
 | 
						|
                int childPropertyOccurrenceCount = 1;
 | 
						|
                for (int j = 1; j < allProperties.Count; j++)
 | 
						|
                {
 | 
						|
                    PropertyDescriptorCollection col2 = allProperties[j];
 | 
						|
                    foreach (PropertyDescriptor propDesc2 in col2)
 | 
						|
                    {
 | 
						|
                        if (ArePropertiesSame(propDesc2, propDesc) && propDesc.Attributes[typeof(MergablePropertyAttribute)].IsDefaultAttribute())
 | 
						|
                        {
 | 
						|
                            childPropertyOccurrenceCount++;
 | 
						|
                            break;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (childPropertyOccurrenceCount == selectedObjectsCount)
 | 
						|
                {
 | 
						|
                    mergedProperties.Add(propDesc);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return new PropertyDescriptorCollection(mergedProperties.ToArray());
 | 
						|
        }
 | 
						|
 | 
						|
        private bool ArePropertiesSame(PropertyDescriptor propDesc2, PropertyDescriptor propDesc)
 | 
						|
        {
 | 
						|
            return propDesc2.Name == propDesc.Name && propDesc2.PropertyType == propDesc.PropertyType;
 | 
						|
        }
 | 
						|
        public static PropertyDescriptor GetProperty(string propertyName, object component, TypeConverter converter)
 | 
						|
        {
 | 
						|
            PropertyDescriptorCollection col = GetProperties(null, component, converter);
 | 
						|
            foreach (PropertyDescriptor item in col)
 | 
						|
            {
 | 
						|
                if (item.Name == propertyName)
 | 
						|
                    return item;
 | 
						|
            }
 | 
						|
            return null;
 | 
						|
        }
 | 
						|
        
 | 
						|
        public static PropertyDescriptorCollection GetProperties(Attribute[] attributes, object component, TypeConverter converter)
 | 
						|
        {
 | 
						|
            return GetProperties(null, attributes, component, converter);
 | 
						|
        }
 | 
						|
 | 
						|
         public static PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, Attribute[] attributes, object component, TypeConverter converter)
 | 
						|
        {
 | 
						|
            if (component == null) return null;
 | 
						|
 | 
						|
            if (component is ICustomTypeDescriptor)
 | 
						|
            {
 | 
						|
                ICustomTypeDescriptor descriptor = (ICustomTypeDescriptor)component;
 | 
						|
                if (attributes != null)
 | 
						|
                    return descriptor.GetProperties(attributes);
 | 
						|
                return descriptor.GetProperties();
 | 
						|
            }
 | 
						|
 | 
						|
            // Note that this assumes that converter supports GetProperties!
 | 
						|
            if (converter != null)
 | 
						|
            {
 | 
						|
                return converter.GetProperties(context, component, attributes);
 | 
						|
            }
 | 
						|
 | 
						|
            Type type = component.GetType();
 | 
						|
            
 | 
						|
            if (attributes != null)
 | 
						|
                return TypeDescriptor.GetProperties(component, attributes);
 | 
						|
 | 
						|
            return TypeDescriptor.GetProperties(component);
 | 
						|
        }
 | 
						|
 | 
						|
        private ePropertyGridHelpType _HelpType = ePropertyGridHelpType.HelpHidden;
 | 
						|
        public ePropertyGridHelpType HelpType
 | 
						|
        {
 | 
						|
            get { return _HelpType; }
 | 
						|
            set { _HelpType = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        public TypeConverter TypeConverter
 | 
						|
        {
 | 
						|
            get { return _Converter; }
 | 
						|
            set { _Converter = value; }
 | 
						|
        }
 | 
						|
        #endregion
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    }
 | 
						|
}
 | 
						|
#endif |