BasePropertyDescriptor.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / Shared / BasePropertyDescriptor.cs / 1305376 / BasePropertyDescriptor.cs

                            // Copyright (c) 1999-2002 Microsoft Corporation. All rights reserved. 
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 
// THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE
// AND INFORMATION REMAINS WITH THE USER. 
// 
using System;
using System.ComponentModel; 
using System.ComponentModel.Design;
using System.Collections;
using System.Collections.Generic;
using System.Resources; 
using System.Reflection;
using System.Globalization; 
using System.Security; 
using System.Security.Permissions;
using System.Workflow.ComponentModel; 
using System.Workflow.ComponentModel.Compiler;

/**********************************************************************
 * NOTE: A copy of this file exists at: WF\Activities\Common 
 * The two files must be kept in [....].  Any change made here must also
 * be made to WF\Activities\Common\BasePropertyDescriptor.cs 
*********************************************************************/ 

namespace System.Workflow.ComponentModel.Design 
{
 	#region Class PropertyDescriptorUtils
	internal static class PropertyDescriptorUtils
	{ 
		internal static ISite GetSite(IServiceProvider serviceProvider, object component)
 		{ 
			ISite site = null; 

            if (component != null) 
            {
                if ((component is IComponent) && ((IComponent)component).Site != null)
                    site = ((IComponent)component).Site;
 
                if (site == null && component.GetType().IsArray && (component as object[]).Length > 0 && (component as object[])[0] is IComponent)
                    site = ((IComponent)(component as object[])[0]).Site; 
 
                if (site == null && serviceProvider != null)
                { 
                    IReferenceService referenceService = serviceProvider.GetService(typeof(IReferenceService)) as IReferenceService;
                    if (referenceService != null)
                    {
                        IComponent baseComponent = referenceService.GetComponent(component); 
                        if (baseComponent != null)
                            site = baseComponent.Site; 
                    } 
                }
            } 

 			if (site == null)
 				site = serviceProvider as ISite;
 
			return site;
 		} 
 
		internal static IComponent GetComponent(ITypeDescriptorContext context)
		{ 
            ISite site = (context != null) ? GetSite(context, context.Instance) : null;
            return (site != null) ? site.Component : null;
		}
 
 		internal static Type GetBaseType(PropertyDescriptor property, object owner, IServiceProvider serviceProvider)
		{ 
 			Type baseType = null; 

            Type ownerType = owner.GetType(); 
            if (owner != null)
            {
 				IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider;
                if (basetypeProvider != null) 
                    baseType = basetypeProvider.GetPropertyType(serviceProvider, property.Name);
            } 
 
			if (baseType == null)
 				baseType = property.PropertyType; 

			return baseType;
		}
 
		internal static void SetPropertyValue(IServiceProvider serviceProvider, PropertyDescriptor propertyDescriptor, object component, object value)
 		{ 
			ComponentChangeDispatcher componentChange = new ComponentChangeDispatcher(serviceProvider, component, propertyDescriptor); 
 			try
 			{ 
				propertyDescriptor.SetValue(component, value);
 			}
			catch (Exception t)
			{ 
				// If there was a problem setting the controls property then we get:
 				// ArgumentException (from properties set method) 
				// ==> Becomes inner exception of TargetInvocationException 
 				// ==> caught here
 				// Propagate the original exception up 
				if (t is TargetInvocationException && t.InnerException != null)
 					throw t.InnerException;
				else
					throw t; 
			}
 			finally 
			{ 
 				componentChange.Dispose();
 			} 
		}
 	}
	#endregion
 
	#region Class ComponentChangeDispatcher
	internal sealed class ComponentChangeDispatcher : IDisposable 
 	{ 
		private IServiceProvider serviceProvider;
 		private object component; 
 		private PropertyDescriptor property;
		private object oldValue;
 		private object newValue;
 
		public ComponentChangeDispatcher(IServiceProvider serviceProvider, object component, PropertyDescriptor propertyDescriptor)
		{ 
			this.serviceProvider = serviceProvider; 
 			this.component = component;
			this.property = propertyDescriptor; 

 			IComponentChangeService changeService = serviceProvider.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
 			if (changeService != null)
			{ 
 				try
				{ 
					newValue = oldValue = propertyDescriptor.GetValue(component); 
					propertyDescriptor.AddValueChanged(component, new EventHandler(OnValueChanged));
 					changeService.OnComponentChanging(component, propertyDescriptor); 
				}
 				catch (CheckoutException coEx)
 				{
					if (coEx == CheckoutException.Canceled) 
 						return;
					throw coEx; 
				} 
			}
 		} 

		public void Dispose()
 		{
 			IComponentChangeService changeService = this.serviceProvider.GetService(typeof(IComponentChangeService)) as IComponentChangeService; 
			if (changeService != null)
 				changeService.OnComponentChanged(this.component, this.property, this.oldValue, this.newValue); 
		} 

		private void OnValueChanged(object sender, EventArgs e) 
		{
 			this.newValue = this.property.GetValue(this.component);
			this.property.RemoveValueChanged(this.component, new EventHandler(OnValueChanged));
 		} 
 	}
	#endregion 
 
 	#region Class DynamicPropertyDescriptor
	internal class DynamicPropertyDescriptor : PropertyDescriptor 
	{
		private IServiceProvider serviceProvider;
 		private PropertyDescriptor realPropertyDescriptor;
 
		public DynamicPropertyDescriptor(IServiceProvider serviceProvider, PropertyDescriptor descriptor)
 			: base(descriptor, null) 
 		{ 
			this.serviceProvider = serviceProvider;
 			this.realPropertyDescriptor = descriptor; 
		}

		public IServiceProvider ServiceProvider
		{ 
 			get
			{ 
 				return this.serviceProvider; 
 			}
		} 

 		public PropertyDescriptor RealPropertyDescriptor
		{
			get 
			{
 				return this.realPropertyDescriptor; 
			} 
 		}
 
 		public override string Category
		{
 			get
			{ 
				return this.realPropertyDescriptor.Category;
			} 
 		} 

		public override AttributeCollection Attributes 
 		{
 			get
			{
                ArrayList attributes = new ArrayList(); 
                attributes.AddRange(this.realPropertyDescriptor.Attributes);
                attributes.Add(new MergablePropertyAttribute(false)); 
                return new AttributeCollection((Attribute[])attributes.ToArray(typeof(Attribute))); 
 			}
		} 

		public override TypeConverter Converter
		{
 			get 
			{
 				return this.realPropertyDescriptor.Converter; 
 			} 
		}
 
 		public override string Description
		{
			get
			{ 
 				return this.realPropertyDescriptor.Description;
			} 
 		} 

        public override string DisplayName 
        {
            get
            {
                return this.realPropertyDescriptor.DisplayName; 
            }
        } 
 
 		public override Type ComponentType
		{ 
 			get
			{
				return this.realPropertyDescriptor.ComponentType;
			} 
 		}
 
		public override Type PropertyType 
 		{
 			get 
			{
 				return this.realPropertyDescriptor.PropertyType;
			}
		} 

		public override bool IsReadOnly 
 		{ 
			get
 			{ 
 				return this.realPropertyDescriptor.IsReadOnly;
			}
 		}
 
		public override void ResetValue(object component)
		{ 
			this.realPropertyDescriptor.ResetValue(component); 
 		}
 
		public override bool CanResetValue(object component)
 		{
 			return this.realPropertyDescriptor.CanResetValue(component);
		} 

 		public override bool ShouldSerializeValue(object component) 
		{ 
			// work around: The real property descriptor is returning false for all the
			// SequentialWorkflow class's properties because they all get replaced with 
 			// InheritedPropertyDescriptors on Initialization (in the ComponentDesigner
			// base class), which is causing problems in the code-only serialization.
 			if (string.Equals(this.realPropertyDescriptor.GetType().FullName, "System.ComponentModel.Design.InheritedPropertyDescriptor", StringComparison.Ordinal))
 				return true; 

			return this.realPropertyDescriptor.ShouldSerializeValue(component); 
 		} 

		public override object GetValue(object component) 
		{
			// When a child property is of type event, component could be null.
 			if (component == null)
				return null; 

 			return this.realPropertyDescriptor.GetValue(component); 
 		} 

		public override void SetValue(object component, object value) 
 		{
			if (component is IComponent)
				this.realPropertyDescriptor.SetValue(component, value);
			else 
 				PropertyDescriptorUtils.SetPropertyValue(ServiceProvider, this.realPropertyDescriptor, component, value);
		} 
 	} 
 	#endregion
 
	#region Class ParameterInfoBasedPropertyDescriptor

 	internal class ParameterInfoBasedPropertyDescriptor : PropertyDescriptor
	{ 
		private Type componentType;
		private string desc = string.Empty; 
 		private bool avoidDuplication = false; 
		private object parameter = null; // Could be either ParameterInfo or PropertyInfo
 		private Type parameterType = null; 
 		private const string parameterPrefix = "(Parameter) ";

		internal ParameterInfoBasedPropertyDescriptor(Type componentType, ParameterInfo paramInfo, bool avoidDuplication, params Attribute[] attributes)
 			: base((paramInfo.Position == -1) ? "(ReturnValue)" : paramInfo.Name, attributes) 
		{
            if (componentType == null) 
                throw new ArgumentNullException("componentType"); 

            if (paramInfo == null) 
                throw new ArgumentNullException("paramInfo");

            if (paramInfo.ParameterType == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_ParameterTypeResolution, paramInfo.Name)); 

			this.componentType = componentType; 
			this.parameter = paramInfo; 
            this.avoidDuplication = avoidDuplication;
            this.parameterType = paramInfo.ParameterType; 

            //Build and cache description
            string qualifier = String.Empty;
            if ((paramInfo.ParameterType != null) && (paramInfo.ParameterType.IsByRef || (paramInfo.IsIn && paramInfo.IsOut))) 
                qualifier = SR.GetString(SR.Ref);
            else if (paramInfo.IsOut || paramInfo.Name == null) 
                qualifier = SR.GetString(SR.Out); 
            else
                qualifier = SR.GetString(SR.In); 
 			this.desc = SR.GetString(SR.ParameterDescription, paramInfo.ParameterType.FullName);
		}

 
 		internal ParameterInfoBasedPropertyDescriptor(Type componentType, string propertyName, Type propertyType, bool avoidDuplication, params Attribute[] attributes)
 			: base(propertyName, attributes) 
		{ 
            if (componentType == null)
                throw new ArgumentNullException("componentType"); 

            if (propertyType == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_ParameterTypeResolution, propertyName));
 
            this.componentType = componentType;
            this.parameterType = propertyType; 
            this.avoidDuplication = avoidDuplication; 
            this.desc = SR.GetString(SR.InvokeParameterDescription, propertyType.FullName.ToString());
 		} 

		internal Type ParameterType
		{
			get 
 			{
				Type type = this.parameterType; 
 				if (type.IsByRef) 
 					type = type.GetElementType();
				return type; 
 			}
		}

		public override string Description 
		{
 			get 
			{ 
 				return this.desc;
 			} 
		}

 		public override string Category
		{ 
			get
			{ 
 				return SR.GetString(SR.Parameters); 
			}
 		} 

 		public override object GetEditor(Type editorBaseType)
		{
            return TypeDescriptor.GetEditor(PropertyType, editorBaseType); 
 		}
 
		public override string DisplayName 
		{
			get 
 			{
				return this.Name;
 			}
 		} 

		public override bool IsReadOnly 
 		{ 
			get
			{ 
				return false;
 			}
		}
 
 		public override Type ComponentType
 		{ 
			get 
 			{
				return this.componentType; 
			}
		}

 		public override string Name 
		{
 			get 
 			{ 
                if (this.avoidDuplication)
                { 
                    // WinOE Bug 10442: should only prefix with "(Parameter)" if there is and existing
                    // member of the same name.
                    return GetParameterPropertyName(this.componentType, base.Name);
                } 
                else
                    return base.Name; 
			} 
 		}
 
        internal static MemberInfo FindMatchingMember(string name, Type ownerType, bool ignoreCase)
        {
            MemberInfo matchingMember = null;
            foreach (MemberInfo memberInfo in ownerType.GetMembers(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) 
            {
                if (memberInfo.Name.Equals(name, ((ignoreCase) ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture))) 
                { 
                    matchingMember = memberInfo;
                    break; 
                }
            }
            return matchingMember;
        } 

		public override Type PropertyType 
		{ 
			get
 			{ 
                Type propertyType = ParameterType;
                if (propertyType == null)
                    propertyType = typeof(ActivityBind);
                return propertyType; 
			}
 		} 
 
 		public override TypeConverter Converter
		{ 
 			get
			{
                //We return this to make sure that we can bind parameters through UI
                return new ActivityBindTypeConverter(); 
			}
		} 
 
 		public override AttributeCollection Attributes
		{ 
 			get
 			{
                ArrayList attributes = new ArrayList();
                attributes.AddRange(base.Attributes); 
                attributes.AddRange(TypeDescriptor.GetAttributes(PropertyType));
                return new AttributeCollection((Attribute[])attributes.ToArray(typeof(Attribute))); 
			} 
 		}
 
		public override void ResetValue(object component)
		{
            if (PropertyType != null && !PropertyType.IsValueType)
                SetValue(component, null); 
		}
 
 		public override bool CanResetValue(object component) 
		{
 			return false; 
 		}

		public override bool ShouldSerializeValue(object component)
 		{ 
			return false;
		} 
 
		public override void SetValue(object component, object value)
 		{ 
			// the logic for notifications is borrowed from ReflectPropertyDescritpor
            if (component == null)
                return;
 
            IServiceProvider serviceProvider = GetSite(component);
            ComponentChangeDispatcher componentChange = (serviceProvider != null) ? new ComponentChangeDispatcher(serviceProvider, component, this) : null; 
 
 			try
 			{ 
                WorkflowParameterBindingCollection parameters = GetParameterBindings(component);
				if (parameters != null)
 				{
					string propertyName = String.Empty; 
					if (this.Name.StartsWith(parameterPrefix, StringComparison.Ordinal))
						propertyName = this.Name.Substring(parameterPrefix.Length); 
 					else 
						propertyName = this.Name;
 
 					WorkflowParameterBinding binding = null;
 					if (parameters.Contains(propertyName))
						binding = parameters[propertyName];
 					else 
					{
						binding = new WorkflowParameterBinding(propertyName); 
						parameters.Add(binding); 
 					}
 
					if (value is ActivityBind)
 						binding.SetBinding(WorkflowParameterBinding.ValueProperty, value as ActivityBind);
 					else
						binding.SetValue(WorkflowParameterBinding.ValueProperty, value); 

 					OnValueChanged(component, EventArgs.Empty); 
				} 
			}
            catch (Exception t) 
            {
                // If there was a problem setting the controls property then we get:
                // ArgumentException (from properties set method)
                // ==> Becomes inner exception of TargetInvocationException 
                // ==> caught here
                // Propagate the original exception up 
                if (t is TargetInvocationException && t.InnerException != null) 
                    throw t.InnerException;
                else 
                    throw t;
            }
            finally
			{ 
 				// Now notify the change service that the change was successful.
                if (componentChange != null) 
                    componentChange.Dispose(); 
			}
 		} 

 		public override object GetValue(object component)
		{
            WorkflowParameterBindingCollection parameters = GetParameterBindings(component); 
            string displayName = this.Name;
 			string propertyName = (displayName.StartsWith(parameterPrefix, StringComparison.Ordinal)) ? displayName.Substring(parameterPrefix.Length) : displayName; 
			if (parameters != null && parameters.Contains(propertyName)) 
			{
				if (parameters[propertyName].IsBindingSet(WorkflowParameterBinding.ValueProperty)) 
 					return parameters[propertyName].GetBinding(WorkflowParameterBinding.ValueProperty);
				else
 					return parameters[propertyName].GetValue(WorkflowParameterBinding.ValueProperty);
 			} 

			return null; 
 		} 

		private WorkflowParameterBindingCollection GetParameterBindings(object component) 
		{
			WorkflowParameterBindingCollection retVal = null;
 			MemberInfo memberInfo = component.GetType().GetProperty("ParameterBindings", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.ExactBinding, null, typeof(WorkflowParameterBindingCollection), new Type[] { }, new ParameterModifier[] { });
			if (memberInfo != null) 
 				retVal = component.GetType().InvokeMember("ParameterBindings", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.ExactBinding, null, component, new object[] { }, CultureInfo.InvariantCulture) as WorkflowParameterBindingCollection;
 			return retVal; 
		} 

        public static string GetParameterPropertyName(Type componentType, string paramName) 
        {
            string paramPropertyName = paramName;
            if (FindMatchingMember(paramName, componentType, false) != null)
                paramPropertyName = parameterPrefix + paramName; 

            return paramPropertyName; 
        } 
 	}
	#endregion 

    #region IPropertyValueProvider Interface
    internal interface IPropertyValueProvider
    { 
        ICollection GetPropertyValues(ITypeDescriptorContext typeDescriptorContext);
    } 
    #endregion 

	#region Class PropertyValueProviderTypeConverter 
	internal class PropertyValueProviderTypeConverter : TypeConverter
 	{
		public PropertyValueProviderTypeConverter()
 		{ 
 		}
 
		public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 
 		{
			// grab all property values 
			IPropertyValueProvider valuesProvider = null;
			object[] instances = context.Instance as object[];
 			if (instances != null && instances.Length > 0)
				valuesProvider = instances[0] as IPropertyValueProvider; 
 			else
 				valuesProvider = context.Instance as IPropertyValueProvider; 
 
			ICollection values = new object[] { };
            if (valuesProvider != null) 
                values = valuesProvider.GetPropertyValues(context);

 			return new StandardValuesCollection(values);
		} 

		public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
		{ 
 			return true;
		} 

 		public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
 		{
			return true; 
 		}
	} 
	#endregion 

    #region Class TypePropertyDescriptor 
    internal class TypePropertyDescriptor : DynamicPropertyDescriptor
    {
        public TypePropertyDescriptor(IServiceProvider serviceProvider, PropertyDescriptor actualPropDesc)
            : base(serviceProvider, actualPropDesc) 
        {
        } 
 
        public override TypeConverter Converter
        { 
            get
            {
                // work around: a direct type comparison would not work because the types in this file are compiled
                // into the component model and the activities dll separately.  The assembly name differs thus 
                // the comparison fails.  Work around by getting the type from the same assembly before doing
                // the comparison. 
                TypeConverter baseTypeConverter = base.Converter; 
                string baseConverterTypeName = baseTypeConverter.GetType().FullName;
                Type baseConverterType = Assembly.GetExecutingAssembly().GetType(baseConverterTypeName); 
                if (baseConverterType != null && typeof(TypePropertyTypeConverter).IsAssignableFrom(baseConverterType))
                    return baseTypeConverter;
                else
                    return new TypePropertyTypeConverter(); 
            }
        } 
 
        public override object GetValue(object component)
        { 
            if (component == null)
                throw new ArgumentNullException("component");

            object value = base.GetValue(component); 

            if (value == null) 
            { 
                // See if there is a value in the user data DesignTimeTypeNames hashtable.
                // If yes, it's probably a wrong type name.  Show the name anyway. 
                DependencyObject dependencyObject = component as DependencyObject;
                if (dependencyObject != null)
                {
                    object key = DependencyProperty.FromName(this.RealPropertyDescriptor.Name, this.RealPropertyDescriptor.ComponentType); 
                    value = Helpers.GetDesignTimeTypeName(dependencyObject, key);
                    if (string.IsNullOrEmpty(value as string)) 
                    { 
                        key = this.RealPropertyDescriptor.ComponentType.FullName + "." + this.RealPropertyDescriptor.Name;
                        value = Helpers.GetDesignTimeTypeName(dependencyObject, key); 
                    }
                }
            }
 
            return value;
        } 
 
        public override void SetValue(object component, object value)
        { 
            if (component == null)
                throw new ArgumentNullException("component");

            if (value != null) 
            {
                Type type = value as Type; 
                ITypeFilterProvider filterProvider = PropertyDescriptorUtils.GetComponent(new TypeDescriptorContext(ServiceProvider, RealPropertyDescriptor, component)) as ITypeFilterProvider; 
                if (filterProvider != null)
                    filterProvider.CanFilterType(type, true);//this will throw an exception if the type is not correctly filterable 
            }

            base.SetValue(component, value);
        } 
    }
    #endregion 
 
    #region Class TypePropertyValueProviderTypeConverter
    internal class TypePropertyValueProviderTypeConverter : TypePropertyTypeConverter 
    {
        // NOTE: Copied from PropertyValueProviderTypeConverter.
        // The purpose of this type converter is so that we can both provide standard values and
        // convert System.Type to string. 
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        { 
            // grab all property values 
            IPropertyValueProvider valuesProvider = null;
            object[] instances = context.Instance as object[]; 
            if (instances != null && instances.Length > 0)
                valuesProvider = instances[0] as IPropertyValueProvider;
            else
                valuesProvider = context.Instance as IPropertyValueProvider; 

            ICollection values = new object[] { }; 
            if (valuesProvider != null && context != null) 
                values = valuesProvider.GetPropertyValues(context);
 
            return new StandardValuesCollection(values);
        }
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        { 
            return true;
        } 
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 
        {
            return true; 
        }
    }
    #endregion
 
    #region Class TypePropertyTypeConverter
    internal class TypePropertyTypeConverter : TypeConverter 
    { 
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        { 
            if (sourceType == null)
                throw new ArgumentNullException("sourceType");

            if (TypeDescriptor.Equals(sourceType, typeof(string))) 
                return true;
 
            return base.CanConvertFrom(context, sourceType); 

        } 

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == null) 
                throw new ArgumentNullException("destinationType");
 
            if (TypeDescriptor.Equals(destinationType, typeof(Type))) 
                return true;
 
            return base.CanConvertTo(context, destinationType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object valueToConvert) 
        {
            string typeName = valueToConvert as string; 
            if (String.IsNullOrEmpty(typeName)) 
                return null;
 
            if (context != null)
            {
                ITypeProvider typeProvider = context.GetService(typeof(ITypeProvider)) as ITypeProvider;
                if (typeProvider != null) 
                    return typeProvider.GetType(typeName, true);
            } 
 
            return base.ConvertFrom(context, culture, valueToConvert);
        } 

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (value is Type && TypeDescriptor.Equals(destinationType, typeof(string))) 
                return ((Type)value).FullName;
 
            return base.ConvertTo(context, culture, value, destinationType); 
        }
    } 
    #endregion
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 1999-2002 Microsoft Corporation. All rights reserved. 
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 
// THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE
// AND INFORMATION REMAINS WITH THE USER. 
// 
using System;
using System.ComponentModel; 
using System.ComponentModel.Design;
using System.Collections;
using System.Collections.Generic;
using System.Resources; 
using System.Reflection;
using System.Globalization; 
using System.Security; 
using System.Security.Permissions;
using System.Workflow.ComponentModel; 
using System.Workflow.ComponentModel.Compiler;

/**********************************************************************
 * NOTE: A copy of this file exists at: WF\Activities\Common 
 * The two files must be kept in [....].  Any change made here must also
 * be made to WF\Activities\Common\BasePropertyDescriptor.cs 
*********************************************************************/ 

namespace System.Workflow.ComponentModel.Design 
{
 	#region Class PropertyDescriptorUtils
	internal static class PropertyDescriptorUtils
	{ 
		internal static ISite GetSite(IServiceProvider serviceProvider, object component)
 		{ 
			ISite site = null; 

            if (component != null) 
            {
                if ((component is IComponent) && ((IComponent)component).Site != null)
                    site = ((IComponent)component).Site;
 
                if (site == null && component.GetType().IsArray && (component as object[]).Length > 0 && (component as object[])[0] is IComponent)
                    site = ((IComponent)(component as object[])[0]).Site; 
 
                if (site == null && serviceProvider != null)
                { 
                    IReferenceService referenceService = serviceProvider.GetService(typeof(IReferenceService)) as IReferenceService;
                    if (referenceService != null)
                    {
                        IComponent baseComponent = referenceService.GetComponent(component); 
                        if (baseComponent != null)
                            site = baseComponent.Site; 
                    } 
                }
            } 

 			if (site == null)
 				site = serviceProvider as ISite;
 
			return site;
 		} 
 
		internal static IComponent GetComponent(ITypeDescriptorContext context)
		{ 
            ISite site = (context != null) ? GetSite(context, context.Instance) : null;
            return (site != null) ? site.Component : null;
		}
 
 		internal static Type GetBaseType(PropertyDescriptor property, object owner, IServiceProvider serviceProvider)
		{ 
 			Type baseType = null; 

            Type ownerType = owner.GetType(); 
            if (owner != null)
            {
 				IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider;
                if (basetypeProvider != null) 
                    baseType = basetypeProvider.GetPropertyType(serviceProvider, property.Name);
            } 
 
			if (baseType == null)
 				baseType = property.PropertyType; 

			return baseType;
		}
 
		internal static void SetPropertyValue(IServiceProvider serviceProvider, PropertyDescriptor propertyDescriptor, object component, object value)
 		{ 
			ComponentChangeDispatcher componentChange = new ComponentChangeDispatcher(serviceProvider, component, propertyDescriptor); 
 			try
 			{ 
				propertyDescriptor.SetValue(component, value);
 			}
			catch (Exception t)
			{ 
				// If there was a problem setting the controls property then we get:
 				// ArgumentException (from properties set method) 
				// ==> Becomes inner exception of TargetInvocationException 
 				// ==> caught here
 				// Propagate the original exception up 
				if (t is TargetInvocationException && t.InnerException != null)
 					throw t.InnerException;
				else
					throw t; 
			}
 			finally 
			{ 
 				componentChange.Dispose();
 			} 
		}
 	}
	#endregion
 
	#region Class ComponentChangeDispatcher
	internal sealed class ComponentChangeDispatcher : IDisposable 
 	{ 
		private IServiceProvider serviceProvider;
 		private object component; 
 		private PropertyDescriptor property;
		private object oldValue;
 		private object newValue;
 
		public ComponentChangeDispatcher(IServiceProvider serviceProvider, object component, PropertyDescriptor propertyDescriptor)
		{ 
			this.serviceProvider = serviceProvider; 
 			this.component = component;
			this.property = propertyDescriptor; 

 			IComponentChangeService changeService = serviceProvider.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
 			if (changeService != null)
			{ 
 				try
				{ 
					newValue = oldValue = propertyDescriptor.GetValue(component); 
					propertyDescriptor.AddValueChanged(component, new EventHandler(OnValueChanged));
 					changeService.OnComponentChanging(component, propertyDescriptor); 
				}
 				catch (CheckoutException coEx)
 				{
					if (coEx == CheckoutException.Canceled) 
 						return;
					throw coEx; 
				} 
			}
 		} 

		public void Dispose()
 		{
 			IComponentChangeService changeService = this.serviceProvider.GetService(typeof(IComponentChangeService)) as IComponentChangeService; 
			if (changeService != null)
 				changeService.OnComponentChanged(this.component, this.property, this.oldValue, this.newValue); 
		} 

		private void OnValueChanged(object sender, EventArgs e) 
		{
 			this.newValue = this.property.GetValue(this.component);
			this.property.RemoveValueChanged(this.component, new EventHandler(OnValueChanged));
 		} 
 	}
	#endregion 
 
 	#region Class DynamicPropertyDescriptor
	internal class DynamicPropertyDescriptor : PropertyDescriptor 
	{
		private IServiceProvider serviceProvider;
 		private PropertyDescriptor realPropertyDescriptor;
 
		public DynamicPropertyDescriptor(IServiceProvider serviceProvider, PropertyDescriptor descriptor)
 			: base(descriptor, null) 
 		{ 
			this.serviceProvider = serviceProvider;
 			this.realPropertyDescriptor = descriptor; 
		}

		public IServiceProvider ServiceProvider
		{ 
 			get
			{ 
 				return this.serviceProvider; 
 			}
		} 

 		public PropertyDescriptor RealPropertyDescriptor
		{
			get 
			{
 				return this.realPropertyDescriptor; 
			} 
 		}
 
 		public override string Category
		{
 			get
			{ 
				return this.realPropertyDescriptor.Category;
			} 
 		} 

		public override AttributeCollection Attributes 
 		{
 			get
			{
                ArrayList attributes = new ArrayList(); 
                attributes.AddRange(this.realPropertyDescriptor.Attributes);
                attributes.Add(new MergablePropertyAttribute(false)); 
                return new AttributeCollection((Attribute[])attributes.ToArray(typeof(Attribute))); 
 			}
		} 

		public override TypeConverter Converter
		{
 			get 
			{
 				return this.realPropertyDescriptor.Converter; 
 			} 
		}
 
 		public override string Description
		{
			get
			{ 
 				return this.realPropertyDescriptor.Description;
			} 
 		} 

        public override string DisplayName 
        {
            get
            {
                return this.realPropertyDescriptor.DisplayName; 
            }
        } 
 
 		public override Type ComponentType
		{ 
 			get
			{
				return this.realPropertyDescriptor.ComponentType;
			} 
 		}
 
		public override Type PropertyType 
 		{
 			get 
			{
 				return this.realPropertyDescriptor.PropertyType;
			}
		} 

		public override bool IsReadOnly 
 		{ 
			get
 			{ 
 				return this.realPropertyDescriptor.IsReadOnly;
			}
 		}
 
		public override void ResetValue(object component)
		{ 
			this.realPropertyDescriptor.ResetValue(component); 
 		}
 
		public override bool CanResetValue(object component)
 		{
 			return this.realPropertyDescriptor.CanResetValue(component);
		} 

 		public override bool ShouldSerializeValue(object component) 
		{ 
			// work around: The real property descriptor is returning false for all the
			// SequentialWorkflow class's properties because they all get replaced with 
 			// InheritedPropertyDescriptors on Initialization (in the ComponentDesigner
			// base class), which is causing problems in the code-only serialization.
 			if (string.Equals(this.realPropertyDescriptor.GetType().FullName, "System.ComponentModel.Design.InheritedPropertyDescriptor", StringComparison.Ordinal))
 				return true; 

			return this.realPropertyDescriptor.ShouldSerializeValue(component); 
 		} 

		public override object GetValue(object component) 
		{
			// When a child property is of type event, component could be null.
 			if (component == null)
				return null; 

 			return this.realPropertyDescriptor.GetValue(component); 
 		} 

		public override void SetValue(object component, object value) 
 		{
			if (component is IComponent)
				this.realPropertyDescriptor.SetValue(component, value);
			else 
 				PropertyDescriptorUtils.SetPropertyValue(ServiceProvider, this.realPropertyDescriptor, component, value);
		} 
 	} 
 	#endregion
 
	#region Class ParameterInfoBasedPropertyDescriptor

 	internal class ParameterInfoBasedPropertyDescriptor : PropertyDescriptor
	{ 
		private Type componentType;
		private string desc = string.Empty; 
 		private bool avoidDuplication = false; 
		private object parameter = null; // Could be either ParameterInfo or PropertyInfo
 		private Type parameterType = null; 
 		private const string parameterPrefix = "(Parameter) ";

		internal ParameterInfoBasedPropertyDescriptor(Type componentType, ParameterInfo paramInfo, bool avoidDuplication, params Attribute[] attributes)
 			: base((paramInfo.Position == -1) ? "(ReturnValue)" : paramInfo.Name, attributes) 
		{
            if (componentType == null) 
                throw new ArgumentNullException("componentType"); 

            if (paramInfo == null) 
                throw new ArgumentNullException("paramInfo");

            if (paramInfo.ParameterType == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_ParameterTypeResolution, paramInfo.Name)); 

			this.componentType = componentType; 
			this.parameter = paramInfo; 
            this.avoidDuplication = avoidDuplication;
            this.parameterType = paramInfo.ParameterType; 

            //Build and cache description
            string qualifier = String.Empty;
            if ((paramInfo.ParameterType != null) && (paramInfo.ParameterType.IsByRef || (paramInfo.IsIn && paramInfo.IsOut))) 
                qualifier = SR.GetString(SR.Ref);
            else if (paramInfo.IsOut || paramInfo.Name == null) 
                qualifier = SR.GetString(SR.Out); 
            else
                qualifier = SR.GetString(SR.In); 
 			this.desc = SR.GetString(SR.ParameterDescription, paramInfo.ParameterType.FullName);
		}

 
 		internal ParameterInfoBasedPropertyDescriptor(Type componentType, string propertyName, Type propertyType, bool avoidDuplication, params Attribute[] attributes)
 			: base(propertyName, attributes) 
		{ 
            if (componentType == null)
                throw new ArgumentNullException("componentType"); 

            if (propertyType == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_ParameterTypeResolution, propertyName));
 
            this.componentType = componentType;
            this.parameterType = propertyType; 
            this.avoidDuplication = avoidDuplication; 
            this.desc = SR.GetString(SR.InvokeParameterDescription, propertyType.FullName.ToString());
 		} 

		internal Type ParameterType
		{
			get 
 			{
				Type type = this.parameterType; 
 				if (type.IsByRef) 
 					type = type.GetElementType();
				return type; 
 			}
		}

		public override string Description 
		{
 			get 
			{ 
 				return this.desc;
 			} 
		}

 		public override string Category
		{ 
			get
			{ 
 				return SR.GetString(SR.Parameters); 
			}
 		} 

 		public override object GetEditor(Type editorBaseType)
		{
            return TypeDescriptor.GetEditor(PropertyType, editorBaseType); 
 		}
 
		public override string DisplayName 
		{
			get 
 			{
				return this.Name;
 			}
 		} 

		public override bool IsReadOnly 
 		{ 
			get
			{ 
				return false;
 			}
		}
 
 		public override Type ComponentType
 		{ 
			get 
 			{
				return this.componentType; 
			}
		}

 		public override string Name 
		{
 			get 
 			{ 
                if (this.avoidDuplication)
                { 
                    // WinOE Bug 10442: should only prefix with "(Parameter)" if there is and existing
                    // member of the same name.
                    return GetParameterPropertyName(this.componentType, base.Name);
                } 
                else
                    return base.Name; 
			} 
 		}
 
        internal static MemberInfo FindMatchingMember(string name, Type ownerType, bool ignoreCase)
        {
            MemberInfo matchingMember = null;
            foreach (MemberInfo memberInfo in ownerType.GetMembers(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) 
            {
                if (memberInfo.Name.Equals(name, ((ignoreCase) ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture))) 
                { 
                    matchingMember = memberInfo;
                    break; 
                }
            }
            return matchingMember;
        } 

		public override Type PropertyType 
		{ 
			get
 			{ 
                Type propertyType = ParameterType;
                if (propertyType == null)
                    propertyType = typeof(ActivityBind);
                return propertyType; 
			}
 		} 
 
 		public override TypeConverter Converter
		{ 
 			get
			{
                //We return this to make sure that we can bind parameters through UI
                return new ActivityBindTypeConverter(); 
			}
		} 
 
 		public override AttributeCollection Attributes
		{ 
 			get
 			{
                ArrayList attributes = new ArrayList();
                attributes.AddRange(base.Attributes); 
                attributes.AddRange(TypeDescriptor.GetAttributes(PropertyType));
                return new AttributeCollection((Attribute[])attributes.ToArray(typeof(Attribute))); 
			} 
 		}
 
		public override void ResetValue(object component)
		{
            if (PropertyType != null && !PropertyType.IsValueType)
                SetValue(component, null); 
		}
 
 		public override bool CanResetValue(object component) 
		{
 			return false; 
 		}

		public override bool ShouldSerializeValue(object component)
 		{ 
			return false;
		} 
 
		public override void SetValue(object component, object value)
 		{ 
			// the logic for notifications is borrowed from ReflectPropertyDescritpor
            if (component == null)
                return;
 
            IServiceProvider serviceProvider = GetSite(component);
            ComponentChangeDispatcher componentChange = (serviceProvider != null) ? new ComponentChangeDispatcher(serviceProvider, component, this) : null; 
 
 			try
 			{ 
                WorkflowParameterBindingCollection parameters = GetParameterBindings(component);
				if (parameters != null)
 				{
					string propertyName = String.Empty; 
					if (this.Name.StartsWith(parameterPrefix, StringComparison.Ordinal))
						propertyName = this.Name.Substring(parameterPrefix.Length); 
 					else 
						propertyName = this.Name;
 
 					WorkflowParameterBinding binding = null;
 					if (parameters.Contains(propertyName))
						binding = parameters[propertyName];
 					else 
					{
						binding = new WorkflowParameterBinding(propertyName); 
						parameters.Add(binding); 
 					}
 
					if (value is ActivityBind)
 						binding.SetBinding(WorkflowParameterBinding.ValueProperty, value as ActivityBind);
 					else
						binding.SetValue(WorkflowParameterBinding.ValueProperty, value); 

 					OnValueChanged(component, EventArgs.Empty); 
				} 
			}
            catch (Exception t) 
            {
                // If there was a problem setting the controls property then we get:
                // ArgumentException (from properties set method)
                // ==> Becomes inner exception of TargetInvocationException 
                // ==> caught here
                // Propagate the original exception up 
                if (t is TargetInvocationException && t.InnerException != null) 
                    throw t.InnerException;
                else 
                    throw t;
            }
            finally
			{ 
 				// Now notify the change service that the change was successful.
                if (componentChange != null) 
                    componentChange.Dispose(); 
			}
 		} 

 		public override object GetValue(object component)
		{
            WorkflowParameterBindingCollection parameters = GetParameterBindings(component); 
            string displayName = this.Name;
 			string propertyName = (displayName.StartsWith(parameterPrefix, StringComparison.Ordinal)) ? displayName.Substring(parameterPrefix.Length) : displayName; 
			if (parameters != null && parameters.Contains(propertyName)) 
			{
				if (parameters[propertyName].IsBindingSet(WorkflowParameterBinding.ValueProperty)) 
 					return parameters[propertyName].GetBinding(WorkflowParameterBinding.ValueProperty);
				else
 					return parameters[propertyName].GetValue(WorkflowParameterBinding.ValueProperty);
 			} 

			return null; 
 		} 

		private WorkflowParameterBindingCollection GetParameterBindings(object component) 
		{
			WorkflowParameterBindingCollection retVal = null;
 			MemberInfo memberInfo = component.GetType().GetProperty("ParameterBindings", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.ExactBinding, null, typeof(WorkflowParameterBindingCollection), new Type[] { }, new ParameterModifier[] { });
			if (memberInfo != null) 
 				retVal = component.GetType().InvokeMember("ParameterBindings", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.ExactBinding, null, component, new object[] { }, CultureInfo.InvariantCulture) as WorkflowParameterBindingCollection;
 			return retVal; 
		} 

        public static string GetParameterPropertyName(Type componentType, string paramName) 
        {
            string paramPropertyName = paramName;
            if (FindMatchingMember(paramName, componentType, false) != null)
                paramPropertyName = parameterPrefix + paramName; 

            return paramPropertyName; 
        } 
 	}
	#endregion 

    #region IPropertyValueProvider Interface
    internal interface IPropertyValueProvider
    { 
        ICollection GetPropertyValues(ITypeDescriptorContext typeDescriptorContext);
    } 
    #endregion 

	#region Class PropertyValueProviderTypeConverter 
	internal class PropertyValueProviderTypeConverter : TypeConverter
 	{
		public PropertyValueProviderTypeConverter()
 		{ 
 		}
 
		public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 
 		{
			// grab all property values 
			IPropertyValueProvider valuesProvider = null;
			object[] instances = context.Instance as object[];
 			if (instances != null && instances.Length > 0)
				valuesProvider = instances[0] as IPropertyValueProvider; 
 			else
 				valuesProvider = context.Instance as IPropertyValueProvider; 
 
			ICollection values = new object[] { };
            if (valuesProvider != null) 
                values = valuesProvider.GetPropertyValues(context);

 			return new StandardValuesCollection(values);
		} 

		public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
		{ 
 			return true;
		} 

 		public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
 		{
			return true; 
 		}
	} 
	#endregion 

    #region Class TypePropertyDescriptor 
    internal class TypePropertyDescriptor : DynamicPropertyDescriptor
    {
        public TypePropertyDescriptor(IServiceProvider serviceProvider, PropertyDescriptor actualPropDesc)
            : base(serviceProvider, actualPropDesc) 
        {
        } 
 
        public override TypeConverter Converter
        { 
            get
            {
                // work around: a direct type comparison would not work because the types in this file are compiled
                // into the component model and the activities dll separately.  The assembly name differs thus 
                // the comparison fails.  Work around by getting the type from the same assembly before doing
                // the comparison. 
                TypeConverter baseTypeConverter = base.Converter; 
                string baseConverterTypeName = baseTypeConverter.GetType().FullName;
                Type baseConverterType = Assembly.GetExecutingAssembly().GetType(baseConverterTypeName); 
                if (baseConverterType != null && typeof(TypePropertyTypeConverter).IsAssignableFrom(baseConverterType))
                    return baseTypeConverter;
                else
                    return new TypePropertyTypeConverter(); 
            }
        } 
 
        public override object GetValue(object component)
        { 
            if (component == null)
                throw new ArgumentNullException("component");

            object value = base.GetValue(component); 

            if (value == null) 
            { 
                // See if there is a value in the user data DesignTimeTypeNames hashtable.
                // If yes, it's probably a wrong type name.  Show the name anyway. 
                DependencyObject dependencyObject = component as DependencyObject;
                if (dependencyObject != null)
                {
                    object key = DependencyProperty.FromName(this.RealPropertyDescriptor.Name, this.RealPropertyDescriptor.ComponentType); 
                    value = Helpers.GetDesignTimeTypeName(dependencyObject, key);
                    if (string.IsNullOrEmpty(value as string)) 
                    { 
                        key = this.RealPropertyDescriptor.ComponentType.FullName + "." + this.RealPropertyDescriptor.Name;
                        value = Helpers.GetDesignTimeTypeName(dependencyObject, key); 
                    }
                }
            }
 
            return value;
        } 
 
        public override void SetValue(object component, object value)
        { 
            if (component == null)
                throw new ArgumentNullException("component");

            if (value != null) 
            {
                Type type = value as Type; 
                ITypeFilterProvider filterProvider = PropertyDescriptorUtils.GetComponent(new TypeDescriptorContext(ServiceProvider, RealPropertyDescriptor, component)) as ITypeFilterProvider; 
                if (filterProvider != null)
                    filterProvider.CanFilterType(type, true);//this will throw an exception if the type is not correctly filterable 
            }

            base.SetValue(component, value);
        } 
    }
    #endregion 
 
    #region Class TypePropertyValueProviderTypeConverter
    internal class TypePropertyValueProviderTypeConverter : TypePropertyTypeConverter 
    {
        // NOTE: Copied from PropertyValueProviderTypeConverter.
        // The purpose of this type converter is so that we can both provide standard values and
        // convert System.Type to string. 
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        { 
            // grab all property values 
            IPropertyValueProvider valuesProvider = null;
            object[] instances = context.Instance as object[]; 
            if (instances != null && instances.Length > 0)
                valuesProvider = instances[0] as IPropertyValueProvider;
            else
                valuesProvider = context.Instance as IPropertyValueProvider; 

            ICollection values = new object[] { }; 
            if (valuesProvider != null && context != null) 
                values = valuesProvider.GetPropertyValues(context);
 
            return new StandardValuesCollection(values);
        }
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        { 
            return true;
        } 
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 
        {
            return true; 
        }
    }
    #endregion
 
    #region Class TypePropertyTypeConverter
    internal class TypePropertyTypeConverter : TypeConverter 
    { 
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        { 
            if (sourceType == null)
                throw new ArgumentNullException("sourceType");

            if (TypeDescriptor.Equals(sourceType, typeof(string))) 
                return true;
 
            return base.CanConvertFrom(context, sourceType); 

        } 

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == null) 
                throw new ArgumentNullException("destinationType");
 
            if (TypeDescriptor.Equals(destinationType, typeof(Type))) 
                return true;
 
            return base.CanConvertTo(context, destinationType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object valueToConvert) 
        {
            string typeName = valueToConvert as string; 
            if (String.IsNullOrEmpty(typeName)) 
                return null;
 
            if (context != null)
            {
                ITypeProvider typeProvider = context.GetService(typeof(ITypeProvider)) as ITypeProvider;
                if (typeProvider != null) 
                    return typeProvider.GetType(typeName, true);
            } 
 
            return base.ConvertFrom(context, culture, valueToConvert);
        } 

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (value is Type && TypeDescriptor.Equals(destinationType, typeof(string))) 
                return ((Type)value).FullName;
 
            return base.ConvertTo(context, culture, value, destinationType); 
        }
    } 
    #endregion
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK