PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
        {
            PropertyDescriptorCollection propertyDescriptorCollection = TypeDescriptor.GetProperties(this.Target);

            if (this.propsToHide != null && this.propsToHide.Length > 0)
            {
                List <PropertyDescriptor> list = new List <PropertyDescriptor>();
                for (int i = 0; i < propertyDescriptorCollection.Count; i++)
                {
                    PropertyDescriptor prop = propertyDescriptorCollection[i];
                    ExtenderControlPropertyAttribute extenderControlPropertyAttribute = (ExtenderControlPropertyAttribute)prop.Attributes[typeof(ExtenderControlPropertyAttribute)];
                    if (extenderControlPropertyAttribute != null)
                    {
                        ExtenderVisiblePropertyAttribute extenderVisiblePropertyAttribute = (ExtenderVisiblePropertyAttribute)prop.Attributes[typeof(ExtenderVisiblePropertyAttribute)];
                        if (extenderVisiblePropertyAttribute != null && extenderVisiblePropertyAttribute.Value)
                        {
                            int num = Array.FindIndex <string>(this.propsToHide, (string s) => s == prop.Name);
                            if (num == -1)
                            {
                                IDReferencePropertyAttribute idreferencePropertyAttribute = (IDReferencePropertyAttribute)prop.Attributes[typeof(IDReferencePropertyAttribute)];
                                Attribute attribute = prop.Attributes[typeof(TypeConverterAttribute)];
                                if (idreferencePropertyAttribute != null && !idreferencePropertyAttribute.IsDefaultAttribute())
                                {
                                    Type type = typeof(TypedControlIDConverter <Control>).GetGenericTypeDefinition();
                                    type = type.MakeGenericType(new Type[]
                                    {
                                        idreferencePropertyAttribute.ReferencedControlType
                                    });
                                    attribute = new TypeConverterAttribute(type);
                                }
                                prop = TypeDescriptor.CreateProperty(prop.ComponentType, prop, new Attribute[]
                                {
                                    BrowsableAttribute.Yes,
                                    attribute
                                });
                                list.Add(prop);
                            }
                        }
                    }
                }
                propertyDescriptorCollection = new PropertyDescriptorCollection(list.ToArray());
            }
            return(propertyDescriptorCollection);
        }
        /// <summary>
        /// Build act-data-* options attribute on control's element
        /// </summary>
        /// <param name="targetControl"></param>
        /// <returns></returns>
        internal static string BuildDataOptionsAttribute(Control targetControl)
        {
            if (!(targetControl is IControlResolver))
            {
                throw new Exception("JQuery control must derived from IControlResolver");
            }

            var ctlType    = targetControl.GetType();
            var properties = ctlType.GetProperties(BindingFlags.Public
                                                   | BindingFlags.Instance
                                                   | BindingFlags.DeclaredOnly).ToList();

            var behaviorIdProp = ctlType.GetProperty("BehaviorID");

            if (behaviorIdProp != null)
            {
                properties.Add(behaviorIdProp);
            }

            var dataOptions = new List <string>();

            foreach (var property in properties)
            {
                if (property.GetSetMethod(false) == null)
                {
                    continue;
                }

                var propType = property.PropertyType;

                if (propType.IsSpecialName)
                {
                    continue;
                }

                var skip        = false;
                var customAttrs = property.GetCustomAttributes(true);

                IDReferencePropertyAttribute idReferencePropAttr    = null;
                UrlPropertyAttribute         urlPropAttr            = null;
                ClientPropertyNameAttribute  clientPropertyNameAttr = null;

                foreach (var customAttr in customAttrs)
                {
                    if (customAttr is PersistenceModeAttribute)
                    {
                        var persistenceModeAttr = customAttr as PersistenceModeAttribute;
                        if (persistenceModeAttr.Mode != PersistenceMode.Attribute)
                        {
                            skip = true;
                            break;
                        }
                    }

                    if (customAttr is BrowsableAttribute)
                    {
                        var browseableAttr = customAttr as BrowsableAttribute;
                        if (!browseableAttr.Browsable)
                        {
                            skip = true;
                            break;
                        }
                    }

                    if (customAttr is IDReferencePropertyAttribute)
                    {
                        idReferencePropAttr = customAttr as IDReferencePropertyAttribute;
                    }

                    if (customAttr is UrlPropertyAttribute)
                    {
                        urlPropAttr = customAttr as UrlPropertyAttribute;
                    }

                    if (customAttr is ClientPropertyNameAttribute)
                    {
                        clientPropertyNameAttr = customAttr as ClientPropertyNameAttribute;
                    }
                }

                if (skip)
                {
                    continue;
                }

                // Determine default property value
                var defaultValueAttr =
                    (DefaultValueAttribute)
                    property.GetCustomAttributes(typeof(DefaultValueAttribute), false).FirstOrDefault();

                var defaultValue = defaultValueAttr != null
                    ? defaultValueAttr.Value
                    : (propType.IsValueType ? Activator.CreateInstance(propType) : null);

                // Determine property value
                var value = property.GetValue(targetControl, null);

                if (idReferencePropAttr != null)
                {
                    var control = (targetControl as IControlResolver).ResolveControl((string)value);
                    if (control == null)
                    {
                        throw new Exception("Can't find control with ID '" + value + "'");
                    }
                    value = control.ClientID;
                }
                else if (urlPropAttr != null)
                {
                    value = targetControl.ResolveClientUrl((string)value);
                }


                // Only add non-default property values
                if (!object.Equals(value, defaultValue))
                {
                    var formatedValue = value.ToString();

                    // Encode and quotize if value is string
                    if (propType.Equals(typeof(string)))
                    {
                        formatedValue = "'" + targetControl.Page.Server.HtmlEncode(formatedValue) + "'";
                    }

                    var propName = clientPropertyNameAttr == null
                        ? property.Name
                        : clientPropertyNameAttr.PropertyName;

                    dataOptions.Add(string.Format("{0}:{1}", CamelCaseFormat(propName), formatedValue));
                }
            }

            // Returns generated data options
            return(string.Join(",", dataOptions.ToArray()));
        }
        PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
        {
            // we'll walk the extenders properties looking for the ones marked as ExtenderControl properties.
            // for those, we'll make them visible, then add them to the list.
            //

            PropertyDescriptorCollection propCollection = TypeDescriptor.GetProperties(this.Target);

            if (_propsToHide != null && _propsToHide.Length > 0)
            {
                List <PropertyDescriptor> props = new List <PropertyDescriptor>();

                for (int i = 0; i < propCollection.Count; i++)
                {
                    PropertyDescriptor prop = propCollection[i];

                    ScriptControlPropertyAttribute extenderPropAttr = (ScriptControlPropertyAttribute)prop.Attributes[typeof(ScriptControlPropertyAttribute)];

                    if (extenderPropAttr == null)
                    {
                        continue;
                    }

                    ExtenderVisiblePropertyAttribute evpa = (ExtenderVisiblePropertyAttribute)prop.Attributes[typeof(ExtenderVisiblePropertyAttribute)];

                    if (evpa == null || !evpa.Value)
                    {
                        // if there isn't an ExtenderVisiblePropertyAttribute on here (the designer adds this),
                        // then we shouldn't process it.  Usually this means the developer marked it as Browsable.False.
                        //
                        continue;
                    }

                    // if the name is in the list, remove browsable from the name.
                    //
                    int index = Array.FindIndex <string>(_propsToHide,
                                                         delegate(string s) {
                        return(s == prop.Name);
                    }
                                                         );

                    if (index != -1)
                    {
                        continue;
                    }

                    // add the drop down if it is selectable.
                    //
                    IDReferencePropertyAttribute controlRefAttr = (IDReferencePropertyAttribute)prop.Attributes[typeof(IDReferencePropertyAttribute)];

                    Attribute tca = prop.Attributes[typeof(TypeConverterAttribute)];

                    if (controlRefAttr != null && !controlRefAttr.IsDefaultAttribute())
                    {
                        Type t = typeof(TypedControlIDConverter <Control>).GetGenericTypeDefinition();

                        t = t.MakeGenericType(controlRefAttr.ReferencedControlType);

                        tca = new TypeConverterAttribute(t);
                    }

                    prop = TypeDescriptor.CreateProperty(prop.ComponentType, prop, BrowsableAttribute.Yes, tca);

                    // add it to the list.
                    //
                    props.Add(prop);
                }

                propCollection = new PropertyDescriptorCollection(props.ToArray());
            }
            return(propCollection);
        }
Example #4
0
        public static void DescribeComponent(object instance, IScriptComponentDescriptor descriptor, IUrlResolutionService urlResolver, IControlResolver controlResolver)
        {
            // validate preconditions
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }
            if (descriptor == null)
            {
                throw new ArgumentNullException("descriptor");
            }
            if (urlResolver == null)
            {
                urlResolver = instance as IUrlResolutionService;
            }
            if (controlResolver == null)
            {
                controlResolver = instance as IControlResolver;
            }

            // describe properties
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(instance);

            foreach (PropertyDescriptor prop in properties)
            {
                ExtenderControlPropertyAttribute propAttr  = null;
                ExtenderControlEventAttribute    eventAttr = null;

                ClientPropertyNameAttribute  nameAttr    = null;
                IDReferencePropertyAttribute idRefAttr   = null;
                UrlPropertyAttribute         urlAttr     = null;
                ElementReferenceAttribute    elementAttr = null;
                ComponentReferenceAttribute  compAttr    = null;

                foreach (Attribute attr in prop.Attributes)
                {
                    Type attrType = attr.GetType();
                    if (attrType == typeof(ExtenderControlPropertyAttribute))
                    {
                        propAttr = attr as ExtenderControlPropertyAttribute;
                    }
                    else if (attrType == typeof(ExtenderControlEventAttribute))
                    {
                        eventAttr = attr as ExtenderControlEventAttribute;
                    }
                    else if (attrType == typeof(ClientPropertyNameAttribute))
                    {
                        nameAttr = attr as ClientPropertyNameAttribute;
                    }
                    else if (attrType == typeof(IDReferencePropertyAttribute))
                    {
                        idRefAttr = attr as IDReferencePropertyAttribute;
                    }
                    else if (attrType == typeof(UrlPropertyAttribute))
                    {
                        urlAttr = attr as UrlPropertyAttribute;
                    }
                    else if (attrType == typeof(ElementReferenceAttribute))
                    {
                        elementAttr = attr as ElementReferenceAttribute;
                    }
                    else if (attrType == typeof(ComponentReferenceAttribute))
                    {
                        compAttr = attr as ComponentReferenceAttribute;
                    }
                }

                string propertyName = prop.Name;

                // Try getting a property attribute
                if (propAttr == null || !propAttr.IsScriptProperty)
                {
                    // Try getting an event attribute
                    if (eventAttr == null || !eventAttr.IsScriptEvent)
                    {
                        continue;
                    }
                }

                // attempt to rename the property/event
                if (nameAttr != null && !string.IsNullOrEmpty(nameAttr.PropertyName))
                {
                    propertyName = nameAttr.PropertyName;
                }

                // determine whether to serialize the value of a property.  readOnly properties should always be serialized
                bool serialize = prop.ShouldSerializeValue(instance) || prop.IsReadOnly;
                if (serialize)
                {
                    // get the value of the property, skip if it is null
                    Control c     = null;
                    object  value = prop.GetValue(instance);
                    if (value == null)
                    {
                        continue;
                    }

                    // convert and resolve the value
                    if (eventAttr != null && prop.PropertyType != typeof(String))
                    {
                        throw new InvalidOperationException("ExtenderControlEventAttribute can only be applied to a property with a PropertyType of System.String.");
                    }
                    else
                    {
                        if (!prop.PropertyType.IsPrimitive && !prop.PropertyType.IsEnum)
                        {
                            // Check if we can use any of our custom converters
                            // (first do a direct lookup on the property type,
                            // but also check all of its base types if nothing
                            // was found)
                            Converter <object, string> customConverter = null;
                            if (!_customConverters.TryGetValue(prop.PropertyType, out customConverter))
                            {
                                foreach (KeyValuePair <Type, Converter <object, string> > pair in _customConverters)
                                {
                                    if (prop.PropertyType.IsSubclassOf(pair.Key))
                                    {
                                        customConverter = pair.Value;
                                        break;
                                    }
                                }
                            }

                            // Use the custom converter if found, otherwise use
                            // its current type converter
                            if (customConverter != null)
                            {
                                value = customConverter(value);
                            }
                            else
                            {
                                // Determine if we should let ASP.NET AJAX handle this type of conversion, as it supports JSON serialization
                                if (propAttr != null && propAttr.UseJsonSerialization)
                                {
                                    // Use ASP.NET JSON serialization
                                }
                                else
                                {
                                    // Use the property's own converter
                                    TypeConverter conv = prop.Converter;

                                    if (value.GetType() == typeof(DateTime))
                                    {
                                        value = ((DateTime)value).ToString("s", CultureInfo.InvariantCulture);
                                    }
                                    else
                                    {
                                        value = conv.ConvertToString(null, CultureInfo.InvariantCulture, value);
                                    }
                                }
                            }
                        }
                        if (idRefAttr != null && controlResolver != null)
                        {
                            c = controlResolver.ResolveControl((string)value);
                        }
                        if (urlAttr != null && urlResolver != null)
                        {
                            value = urlResolver.ResolveClientUrl((string)value);
                        }
                    }

                    // add the value as an appropriate description
                    if (eventAttr != null)
                    {
                        descriptor.AddEvent(propertyName, (string)value);
                    }
                    else if (elementAttr != null)
                    {
                        if (c == null && controlResolver != null)
                        {
                            c = controlResolver.ResolveControl((string)value);
                        }
                        if (c != null)
                        {
                            value = c.ClientID;
                        }
                        descriptor.AddElementProperty(propertyName, (string)value);
                    }
                    else if (compAttr != null)
                    {
                        if (c == null && controlResolver != null)
                        {
                            c = controlResolver.ResolveControl((string)value);
                        }
                        if (c != null)
                        {
                            ExtenderControlBase ex = c as ExtenderControlBase;
                            if (ex != null && ex.BehaviorID.Length > 0)
                            {
                                value = ex.BehaviorID;
                            }
                            else
                            {
                                value = c.ClientID;
                            }
                        }
                        descriptor.AddComponentProperty(propertyName, (string)value);
                    }
                    else
                    {
                        if (c != null)
                        {
                            value = c.ClientID;
                        }
                        descriptor.AddProperty(propertyName, value);
                    }
                }
            }

            // determine if we should describe methods
            foreach (MethodInfo method in instance.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public))
            {
                ExtenderControlMethodAttribute methAttr = (ExtenderControlMethodAttribute)Attribute.GetCustomAttribute(method, typeof(ExtenderControlMethodAttribute));
                if (methAttr == null || !methAttr.IsScriptMethod)
                {
                    continue;
                }

                // We only need to support emitting the callback target and registering the WebForms.js script if there is at least one valid method
                Control control = instance as Control;
                if (control != null)
                {
                    // Force WebForms.js
                    control.Page.ClientScript.GetCallbackEventReference(control, null, null, null);

                    // Add the callback target
                    descriptor.AddProperty("_callbackTarget", control.UniqueID);
                }
                break;
            }
        }
        private static Dictionary <string, object> BuildGraph(object obj, IUrlResolutionService uriResolver,
                                                              IControlResolver controlResolver)
        {
            Dictionary <string, object>  dict = new Dictionary <string, object>();
            PropertyDescriptorCollection pdc  = TypeDescriptor.GetProperties(obj);

            foreach (PropertyDescriptor pd in pdc)
            {
                ExtenderControlPropertyAttribute ecpa = GetAttribute <ExtenderControlPropertyAttribute>(pd);

                ClientPropertyNameAttribute    cpna = GetAttribute <ClientPropertyNameAttribute>(pd);
                IDReferencePropertyAttribute   idr  = GetAttribute <IDReferencePropertyAttribute>(pd);
                UrlPropertyAttribute           ura  = GetAttribute <UrlPropertyAttribute>(pd);
                ExtenderControlMethodAttribute ecma = GetAttribute <ExtenderControlMethodAttribute>(pd);
                ExtenderControlEventAttribute  ecea = GetAttribute <ExtenderControlEventAttribute>(pd);
                ElementReferenceAttribute      era  = GetAttribute <ElementReferenceAttribute>(pd);
                ComponentReferenceAttribute    cra  = GetAttribute <ComponentReferenceAttribute>(pd);
                if (ecpa == null && cra == null && cpna == null && era == null)
                {
                    continue;
                }


                string propName =
                    cpna != null && !string.IsNullOrEmpty(cpna.PropertyName)
                        ? cpna.PropertyName
                        : pd.Name;


                if (propName == "ClientClassName")
                {
                    propName = "typeToBuild";
                }

                object o     = null;
                object value = pd.GetValue(obj);
                if (value == null)
                {
                    continue;
                }

                if (value as IClientClass != null && ((IClientClass)value).NotSet)
                {
                    continue;
                }

                if (value as ClientEvalScript != null && string.IsNullOrEmpty((value as ClientEvalScript).ClientScript))
                {
                    continue;
                }

                if (pd.PropertyType == typeof(string))
                {
                    o = value;
                    if (ura != null)
                    {
                        o = uriResolver.ResolveClientUrl((string)o);
                    }
                    else if (idr != null || cra != null)
                    {
                        o = BuildGraph(new Reference
                        {
                            ReferenceType = ReferenceType.Component,
                            ClientId      = controlResolver.ResolveControl((string)o).ClientID
                        }, uriResolver, controlResolver);
                    }
                    else if (era != null)
                    {
                        Control c = controlResolver.ResolveControl((string)o);
                        o = BuildGraph(
                            new Reference
                        {
                            ReferenceType = ReferenceType.Element, ClientId = c == null ? (string)o : c.ClientID
                        },
                            uriResolver, controlResolver);
                    }
                }
                else if (value is IEnumerable)
                {
                    List <object> lst = new List <object>();
                    foreach (object a in (IEnumerable)value)
                    {
                        object b;
                        if (a as IUICollectionItem != null)
                        {
                            b = a is UriValue
                                    ? uriResolver.ResolveClientUrl(((UriValue)a).Value.ToString())
                                    : ((IUICollectionItem)a).Value;
                        }
                        else
                        {
                            b = BuildGraph(a, uriResolver, controlResolver);
                        }
                        if (b != null)
                        {
                            lst.Add(b);
                        }
                    }
                    if (lst.Count > 0)
                    {
                        o = lst;
                    }
                }
                else if (pd.PropertyType.IsEnum)
                {
                    o = Enum.GetName(pd.PropertyType, value);
                }
                else if (pd.PropertyType.IsPrimitive || pd.PropertyType.IsValueType)
                {
                    o = value;
                }
                else
                {
                    o = BuildGraph(value, uriResolver, controlResolver);
                }

                if (o != null)
                {
                    dict.Add(propName, o);
                }
            }
            return(dict.Count > 0 ? dict : null);
        }