public ExtendedPropertyDescriptor(PropertyDescriptor extender, Attribute[] attributes) : base(extender, attributes) { ExtenderProvidedPropertyAttribute attribute = extender.Attributes[typeof(ExtenderProvidedPropertyAttribute)] as ExtenderProvidedPropertyAttribute; ReflectPropertyDescriptor extenderProperty = attribute.ExtenderProperty as ReflectPropertyDescriptor; this.extenderInfo = extenderProperty; this.provider = attribute.Provider; }
public void RemoveExtenderProvider (IExtenderProvider provider) { if (_extenderProviders != null) { if (_extenderProviders.Contains (provider)) _extenderProviders.Remove (provider); } }
public void AddExtenderProvider (IExtenderProvider provider) { if (_extenderProviders != null) { if (!_extenderProviders.Contains (provider)) _extenderProviders.Add (provider); } }
public int RegisterExtenderProvider(IExtenderProvider extenderProvider) { int cookie = this.lastCookie + 1; this.extenderProviders.Add(cookie, extenderProvider); this.lastCookie = cookie; return cookie; }
/// <devdoc> /// Creates a new ExtenderProvidedPropertyAttribute. /// </devdoc> internal static ExtenderProvidedPropertyAttribute Create(PropertyDescriptor extenderProperty, Type receiverType, IExtenderProvider provider) { ExtenderProvidedPropertyAttribute e = new ExtenderProvidedPropertyAttribute(); e.extenderProperty = extenderProperty; e.receiverType = receiverType; e.provider = provider; return e; }
internal ExtenderProvidedPropertyAttribute (PropertyDescriptor extenderProperty, IExtenderProvider provider, Type receiverType) { this.extenderProperty = extenderProperty; this.provider = provider; this.receiverType = receiverType; }
// Call this method to create a ExtenderProvidedPropertyAttribute and set it's values internal static ExtenderProvidedPropertyAttribute CreateAttribute (PropertyDescriptor extenderProperty, IExtenderProvider provider, Type receiverType) { ExtenderProvidedPropertyAttribute NewAttribute = new ExtenderProvidedPropertyAttribute(); NewAttribute.extender = extenderProperty; NewAttribute.receiver = receiverType; NewAttribute.extenderProvider = provider; return NewAttribute; }
public IExtenderProvider[] GetExtenderProviders() { if (_extenderProviders != null) { IExtenderProvider[] result = new IExtenderProvider[_extenderProviders.Count]; _extenderProviders.CopyTo (result, 0); return result; } return null; }
IExtenderProvider[] IExtenderListService.GetExtenderProviders() { if (this._providers != null) { IExtenderProvider[] array = new IExtenderProvider[this._providers.Count]; this._providers.CopyTo(array, 0); return(array); } return(new IExtenderProvider[0]); }
public void TableLayoutPanel_CanExtend_Control_ReturnsExpected() { var control = new ScrollableControl(); var panel = new TableLayoutPanel(); IExtenderProvider provider = panel; Assert.False(provider.CanExtend(control)); panel.Controls.Add(control); Assert.True(provider.CanExtend(control)); }
public void RemoveExtenderProvider(IExtenderProvider provider) { if (_extenderProviders != null) { if (_extenderProviders.Contains(provider)) { _extenderProviders.Remove(provider); } } }
IExtenderProvider[] IExtenderListService.GetExtenderProviders() { if (this._providers != null) { IExtenderProvider[] array = new IExtenderProvider[this._providers.Count]; this._providers.CopyTo(array, 0); return array; } return new IExtenderProvider[0]; }
public void AddExtenderProvider(IExtenderProvider provider) { if (_extenderProviders != null) { if (!_extenderProviders.Contains(provider)) { _extenderProviders.Add(provider); } } }
/// <summary> /// Gets the set of extender providers for the component. /// </summary> IExtenderProvider[] IExtenderListService.GetExtenderProviders() { if (_providers != null) { IExtenderProvider[] providers = new IExtenderProvider[_providers.Count]; _providers.CopyTo(providers, 0); return(providers); } return(new IExtenderProvider[0]); }
/// <summary> /// Apply a resource for an extender provider to the given control /// </summary> /// <param name="extenderProviders">Extender providers for the parent control indexed by type</param> /// <param name="control">The control that the extended resource is associated with</param> /// <param name="propertyName">The extender provider property name</param> /// <param name="value">The value to apply</param> /// <remarks> /// This can be overridden to add support for other ExtenderProviders. The default implementation /// handles <see cref="ToolTip">ToolTips</see>, <see cref="HelpProvider">HelpProviders</see>, /// and <see cref="ErrorProvider">ErrorProviders</see> /// </remarks> protected virtual void ApplyExtenderResource(Dictionary <Type, IExtenderProvider> extenderProviders, Control control, string propertyName, object value) { IExtenderProvider extender = null; if (propertyName == "ToolTip") { if (extenderProviders.TryGetValue(typeof(ToolTip), out extender)) { (extender as ToolTip).SetToolTip(control, value as string); } } else if (propertyName == "HelpKeyword") { if (extenderProviders.TryGetValue(typeof(HelpProvider), out extender)) { (extender as HelpProvider).SetHelpKeyword(control, value as string); } } else if (propertyName == "HelpString") { if (extenderProviders.TryGetValue(typeof(HelpProvider), out extender)) { (extender as HelpProvider).SetHelpString(control, value as string); } } else if (propertyName == "ShowHelp") { if (extenderProviders.TryGetValue(typeof(HelpProvider), out extender)) { (extender as HelpProvider).SetShowHelp(control, (bool)value); } } else if (propertyName == "Error") { if (extenderProviders.TryGetValue(typeof(ErrorProvider), out extender)) { (extender as ErrorProvider).SetError(control, value as string); } } else if (propertyName == "IconAlignment") { if (extenderProviders.TryGetValue(typeof(ErrorProvider), out extender)) { (extender as ErrorProvider).SetIconAlignment(control, (ErrorIconAlignment)value); } } else if (propertyName == "IconPadding") { if (extenderProviders.TryGetValue(typeof(ErrorProvider), out extender)) { (extender as ErrorProvider).SetIconPadding(control, (int)value); } } }
internal void ExtenderResetValue(IExtenderProvider provider, object component, PropertyDescriptor notifyDesc) { if (DefaultValue != s_noValue) { ExtenderSetValue(provider, component, DefaultValue, notifyDesc); } else if (AmbientValue != s_noValue) { ExtenderSetValue(provider, component, AmbientValue, notifyDesc); } else if (ResetMethodValue != null) { ISite site = GetSite(component); IComponentChangeService changeService = null; object oldValue = null; object newValue; // Announce that we are about to change this component if (site != null) { changeService = (IComponentChangeService)site.GetService(typeof(IComponentChangeService)); } // Make sure that it is ok to send the onchange events if (changeService != null) { oldValue = ExtenderGetValue(provider, component); try { changeService.OnComponentChanging(component, notifyDesc); } catch (CheckoutException coEx) { if (coEx == CheckoutException.Canceled) { return; } throw; } } provider = (IExtenderProvider)GetInvocationTarget(_componentClass, provider); if (ResetMethodValue != null) { ResetMethodValue.Invoke(provider, new object[] { component }); // Now notify the change service that the change was successful. if (changeService != null) { newValue = ExtenderGetValue(provider, component); changeService.OnComponentChanged(component, notifyDesc, oldValue, newValue); } } } }
public IExtenderProvider[] GetExtenderProviders() { if (_extenderProviders != null) { IExtenderProvider[] result = new IExtenderProvider[_extenderProviders.Count]; _extenderProviders.CopyTo(result, 0); return(result); } return(null); }
public void CanExtend_InvokeWithParent_ReturnsTrue() { var panel = new FlowLayoutPanel(); var control = new Control { Parent = panel }; IExtenderProvider extenderProvider = panel; Assert.True(extenderProvider.CanExtend(control)); }
public void FlowLayoutPanel_CanExtend_InvokeWithParent_ReturnsTrue() { using var control = new FlowLayoutPanel(); using var extendee = new Control { Parent = control }; IExtenderProvider extenderProvider = control; Assert.True(extenderProvider.CanExtend(extendee)); }
/// <summary> /// Gets the set of extender providers for the component. /// </summary> IExtenderProvider[] IExtenderListService.GetExtenderProviders() { if (_providers is not null) { IExtenderProvider[] providers = new IExtenderProvider[_providers.Count]; _providers.CopyTo(providers, 0); return(providers); } return(Array.Empty <IExtenderProvider>()); }
void IExtenderProviderService.RemoveExtenderProvider(IExtenderProvider provider) { if (provider == null) { throw new ArgumentNullException("provider"); } if (this._providers != null) { this._providers.Remove(provider); } }
/// <summary> /// Removes an extender provider. /// </summary> void IExtenderProviderService.RemoveExtenderProvider(IExtenderProvider provider) { if (provider == null) { throw new ArgumentNullException(nameof(provider)); } if (_providers != null) { _providers.Remove(provider); } }
public ExtendedPropertyDescriptor(ReflectPropertyDescriptor extenderInfo, Type receiverType, IExtenderProvider provider, Attribute[] attributes) : base(extenderInfo, attributes) { ArrayList list = new ArrayList(this.AttributeArray); list.Add(ExtenderProvidedPropertyAttribute.Create(extenderInfo, receiverType, provider)); if (extenderInfo.IsReadOnly) { list.Add(ReadOnlyAttribute.Yes); } Attribute[] array = new Attribute[list.Count]; list.CopyTo(array, 0); this.AttributeArray = array; this.extenderInfo = extenderInfo; this.provider = provider; }
public ExtendedPropertyDescriptor(PropertyDescriptor extender, Attribute[] attributes) : base(extender, attributes) { Debug.Assert(extender != null, "The original PropertyDescriptor must be non-null"); ExtenderProvidedPropertyAttribute attr = extender.Attributes[typeof(ExtenderProvidedPropertyAttribute)] as ExtenderProvidedPropertyAttribute; Debug.Assert(attr != null, "The original PropertyDescriptor does not have an ExtenderProvidedPropertyAttribute"); ReflectPropertyDescriptor reflectDesc = attr.ExtenderProperty as ReflectPropertyDescriptor; Debug.Assert(reflectDesc != null, "The original PropertyDescriptor has an invalid ExtenderProperty"); this.extenderInfo = reflectDesc; this.provider = attr.Provider; }
internal void ExtenderSetValue(IExtenderProvider provider, object component, object value, PropertyDescriptor notifyDesc) { if (provider != null) { ISite site = GetSite(component); IComponentChangeService changeService = null; object oldValue = null; // Announce that we are about to change this component // if (site != null) { changeService = (IComponentChangeService)site.GetService(typeof(IComponentChangeService)); Debug.Assert(!CompModSwitches.CommonDesignerServices.Enabled || changeService != null, "IComponentChangeService not found"); } // Make sure that it is ok to send the onchange events // if (changeService != null) { oldValue = ExtenderGetValue(provider, component); try { changeService.OnComponentChanging(component, notifyDesc); } catch (CheckoutException coEx) { if (coEx == CheckoutException.Canceled) { return; } throw coEx; } } provider = (IExtenderProvider)GetInvokee(componentClass, provider); if (SetMethodValue != null) { SetMethodValue.Invoke(provider, new object[] { component, value }); // Now notify the change service that the change was successful. // if (changeService != null) { changeService.OnComponentChanged(component, notifyDesc, oldValue, value); } } } }
public ExtendedPropertyDescriptor(PropertyDescriptor extender, Attribute[] attributes) : base(extender, attributes) { Debug.Assert(extender != null, "The original PropertyDescriptor must be non-null"); ExtenderProvidedPropertyAttribute attr = extender.Attributes[typeof(ExtenderProvidedPropertyAttribute)] as ExtenderProvidedPropertyAttribute; Debug.Assert(attr != null, "The original PropertyDescriptor does not have an ExtenderProvidedPropertyAttribute"); ReflectPropertyDescriptor reflectDesc = attr.ExtenderProperty as ReflectPropertyDescriptor; Debug.Assert(reflectDesc != null, "The original PropertyDescriptor has an invalid ExtenderProperty"); _extenderInfo = reflectDesc; _provider = attr.Provider; }
/// <summary> /// Adds an extender provider. /// </summary> void IExtenderProviderService.AddExtenderProvider(IExtenderProvider provider) { ArgumentNullException.ThrowIfNull(provider); if (_providers is null) { _providers = new ArrayList(4); } if (_providers.Contains(provider)) { throw new ArgumentException(string.Format(SR.ExtenderProviderServiceDuplicateProvider, provider), nameof(provider)); } _providers.Add(provider); }
void IExtenderProviderService.AddExtenderProvider(IExtenderProvider provider) { if (provider == null) { throw new ArgumentNullException("provider"); } if (this._providers == null) { this._providers = new ArrayList(4); } if (this._providers.Contains(provider)) { throw new ArgumentException(System.Design.SR.GetString("ExtenderProviderServiceDuplicateProvider", new object[] { provider })); } this._providers.Add(provider); }
internal void ExtenderResetValue(IExtenderProvider provider, object component, PropertyDescriptor notifyDesc) { if (this.DefaultValue != noValue) { this.ExtenderSetValue(provider, component, this.DefaultValue, notifyDesc); } else if (this.AmbientValue != noValue) { this.ExtenderSetValue(provider, component, this.AmbientValue, notifyDesc); } else if (this.ResetMethodValue != null) { ISite site = MemberDescriptor.GetSite(component); IComponentChangeService service = null; object oldValue = null; if (site != null) { service = (IComponentChangeService)site.GetService(typeof(IComponentChangeService)); } if (service != null) { oldValue = this.ExtenderGetValue(provider, component); try { service.OnComponentChanging(component, notifyDesc); } catch (CheckoutException exception) { if (exception != CheckoutException.Canceled) { throw exception; } return; } } provider = (IExtenderProvider)this.GetInvocationTarget(this.componentClass, provider); if (this.ResetMethodValue != null) { this.ResetMethodValue.Invoke(provider, new object[] { component }); if (service != null) { object newValue = this.ExtenderGetValue(provider, component); service.OnComponentChanged(component, notifyDesc, oldValue, newValue); } } } }
/// <devdoc> /// Creates a new extended property info. Callers can then treat this as /// a standard property. /// </devdoc> public DebugExtendedPropertyDescriptor(DebugReflectPropertyDescriptor extenderInfo, Type receiverType, IExtenderProvider provider, Attribute[] attributes) : base(extenderInfo, attributes) { Debug.Assert(extenderInfo != null, "DebugExtendedPropertyDescriptor must have extenderInfo"); Debug.Assert(provider != null, "DebugExtendedPropertyDescriptor must have provider"); ArrayList attrList = new ArrayList(AttributeArray); attrList.Add(ExtenderProvidedPropertyAttribute.Create(extenderInfo, receiverType, provider)); if (extenderInfo.IsReadOnly) { attrList.Add(ReadOnlyAttribute.Yes); } Attribute[] temp = new Attribute[attrList.Count]; attrList.CopyTo(temp, 0); AttributeArray = temp; this.extenderInfo = extenderInfo; this.provider = provider; }
/// <summary> /// Adds an extender provider. /// </summary> void IExtenderProviderService.AddExtenderProvider(IExtenderProvider provider) { if (provider == null) { throw new ArgumentNullException("provider"); } if (_providers == null) { _providers = new ArrayList(4); } if (_providers.Contains(provider)) { throw new ArgumentException(string.Format(SR.ExtenderProviderServiceDuplicateProvider, provider)); } _providers.Add(provider); }
private readonly IExtenderProvider _provider; // the guy providing it /// <summary> /// Creates a new extended property info. Callers can then treat this as /// a standard property. /// </summary> public ExtendedPropertyDescriptor(ReflectPropertyDescriptor extenderInfo, Type receiverType, IExtenderProvider provider, Attribute[] attributes) : base(extenderInfo, attributes) { Debug.Assert(extenderInfo != null, "ExtendedPropertyDescriptor must have extenderInfo"); Debug.Assert(provider != null, "ExtendedPropertyDescriptor must have provider"); ArrayList attrList = new ArrayList(AttributeArray); attrList.Add(ExtenderProvidedPropertyAttribute.Create(extenderInfo, receiverType, provider)); if (extenderInfo.IsReadOnly) { attrList.Add(ReadOnlyAttribute.Yes); } Attribute[] temp = new Attribute[attrList.Count]; attrList.CopyTo(temp, 0); AttributeArray = temp; _extenderInfo = extenderInfo; _provider = provider; }
internal bool ExtenderCanResetValue(IExtenderProvider provider, object component) { if (DefaultValue != noValue) { return !object.Equals(ExtenderGetValue(provider, component),defaultValue); } MethodInfo reset = ResetMethodValue; if (reset != null) { MethodInfo shouldSerialize = ShouldSerializeMethodValue; if (shouldSerialize != null) { try { provider = (IExtenderProvider)GetDebugInvokee(componentClass, provider); return (bool)shouldSerialize.Invoke(provider, new object[] { component}); } catch {} } } else { return true; } return false; }
public void RemoveExtenderProvider (IExtenderProvider provider) { extenders.Remove (provider); }
public void AddExtenderProvider (IExtenderProvider provider) { extenders.Add (provider); }
// Call this method to create a ExtenderProvidedPropertyAttribute and set it's values internal static ExtenderProvidedPropertyAttribute CreateAttribute(PropertyDescriptor extenderProperty, IExtenderProvider provider, Type receiverType) { ExtenderProvidedPropertyAttribute NewAttribute = new ExtenderProvidedPropertyAttribute(); NewAttribute.extender = extenderProperty; NewAttribute.receiver = receiverType; NewAttribute.extenderProvider = provider; return(NewAttribute); }
int ObjectExtenders.RegisterExtenderProvider(string ExtenderCATID, string ExtenderName, IExtenderProvider ExtenderProvider, string LocalizedName) { throw new Exception("The method or operation is not implemented."); }
public PropertyStash(ArrayList props, IExtenderProvider[] providers, object instance) { Properties = props; extenderHash = HashExtenders(providers, instance); }
/// <summary> /// Removes an extender provider. /// </summary> void IExtenderProviderService.RemoveExtenderProvider(IExtenderProvider provider) { ArgumentNullException.ThrowIfNull(provider); _providers?.Remove(provider); }
/// <devdoc> /// Retrieves filtered, wrapped extended properties based on the provider and the extenderInfos for this type of provider. /// These are the extended properties that will be handed out to components through /// getExtendedProperties and getMergedProperties. These are wrapped versions of what is returned /// through getExtenders. They are filtered based on the attributes. They are sorted /// based on the sort property. /// </devdoc> private IList GetWrappedExtenders(IExtenderProvider provider) { Debug.WriteLineIf(CompDescrSwitch.TraceVerbose, "GetWrappedExtenders"); if (wrappedExtenderTable == null) { wrappedExtenderTable = new Hashtable(); } if (provider == null) { return null; } Type providerType = ((object)provider).GetType(); if (!componentType.IsAssignableFrom(providerType)) { throw new ArgumentException(SR.GetString(SR.ErrorBadExtenderType, providerType.Name, componentType.Name), "provider"); } bool sitedProvider = false; if (provider is IComponent && ((IComponent)provider).Site != null) { sitedProvider = true; } IList wrappedExtenders = null; lock(this) { wrappedExtenders = (IList) wrappedExtenderTable[provider]; if (wrappedExtenders == null) { Debug.WriteLineIf(CompDescrSwitch.TraceVerbose, "\tentry not found in table... creating"); IList extenders = GetExtenders(); Debug.WriteLineIf(CompDescrSwitch.TraceVerbose, "\tfound " + extenders.Count.ToString(CultureInfo.InvariantCulture) + " extenders"); wrappedExtenders = new ArrayList(extenders.Count); for (int i = 0; i < extenders.Count; i++) { DebugReflectPropertyDescriptor ex = (DebugReflectPropertyDescriptor)extenders[i]; Attribute[] attrs = null; // If the extender provider is not a sited component, then mark all // of its properties as design time only, since there is no way we // can persist them. We can assume this because this is only called if // we could get the extender provider list from a component site. // if (!sitedProvider) { attrs = new Attribute[] {DesignOnlyAttribute.Yes}; } wrappedExtenders.Add(new DebugExtendedPropertyDescriptor(ex, ex.ExtenderGetReceiverType(), provider, attrs)); } wrappedExtenderTable[provider] = wrappedExtenders; } else { Debug.WriteLineIf(CompDescrSwitch.TraceVerbose, "\tentry found in table..."); } } return wrappedExtenders; }
internal void ExtenderSetValue(IExtenderProvider provider, object component, object value, PropertyDescriptor notifyDesc) { if (provider != null) { ISite site = GetSite(component); IComponentChangeService changeService = null; object oldValue = null; // Announce that we are about to change this component // if (site != null) { changeService = (IComponentChangeService)site.GetService(typeof(IComponentChangeService)); Debug.Assert(!CompModSwitches.CommonDesignerServices.Enabled || changeService != null, "IComponentChangeService not found"); } // Make sure that it is ok to send the onchange events // if (changeService != null) { oldValue = ExtenderGetValue(provider, component); try { changeService.OnComponentChanging(component, notifyDesc); } catch (CheckoutException coEx) { if (coEx == CheckoutException.Canceled) { return; } throw coEx; } } provider = (IExtenderProvider)GetDebugInvokee(componentClass, provider); if (SetMethodValue != null) { SetMethodValue.Invoke(provider, new object[] { component, value}); // Now notify the change service that the change was successful. // if (changeService != null) { changeService.OnComponentChanged(component, notifyDesc, oldValue, value); } } } }
private readonly IExtenderProvider provider; // the guy providing it /// <include file='doc\ExtendedPropertyDescriptor.uex' path='docs/doc[@for="ExtendedPropertyDescriptor.ExtendedPropertyDescriptor"]/*' /> /// <devdoc> /// Creates a new extended property info. Callers can then treat this as /// a standard property. /// </devdoc> public ExtendedPropertyDescriptor(ReflectPropertyDescriptor extenderInfo, Type receiverType, IExtenderProvider provider) : this(extenderInfo, receiverType, provider, null) { }
/// <devdoc> /// Creates a new ExtenderProvidedPropertyAttribute. /// </devdoc> internal static ExtenderProvidedPropertyAttribute Create(PropertyDescriptor extenderProperty, Type receiverType, IExtenderProvider provider) { ExtenderProvidedPropertyAttribute e = new ExtenderProvidedPropertyAttribute(); e.extenderProperty = extenderProperty; e.receiverType = receiverType; e.provider = provider; return(e); }
int ObjectExtenders.RegisterExtenderProvider(string extenderCategory, string extenderName, IExtenderProvider extenderProvider, string localizedName) { return this.RegisterExtenderProvider(extenderProvider); }
internal Type ExtenderGetType(IExtenderProvider provider) { return PropertyType; }
internal object ExtenderGetValue(IExtenderProvider provider, object component) { if (provider != null) { provider = (IExtenderProvider)GetDebugInvokee(componentClass, provider); return GetMethodValue.Invoke(provider, new object[] { component}); } return null; }
public void RemoveExtenderProvider(IExtenderProvider provider) { }
internal bool ExtenderShouldSerializeValue(IExtenderProvider provider, object component) { provider = (IExtenderProvider)GetDebugInvokee(componentClass, provider); if (IsReadOnly) { if (ShouldSerializeMethodValue != null) { try { return (bool)ShouldSerializeMethodValue.Invoke(provider, new object[] {component}); } catch {} } return Attributes.Contains(DesignerSerializationVisibilityAttribute.Content); } else if (DefaultValue == noValue) { if (ShouldSerializeMethodValue != null) { try { return (bool)ShouldSerializeMethodValue.Invoke(provider, new object[] {component}); } catch {} } return true; } return !object.Equals(DefaultValue, ExtenderGetValue(provider, component)); }
/// <devdoc> /// Retrieves the set of extender providers providing services for the given component. /// </devdoc> private IExtenderProvider[] GetExtenderProviders(ISite site) { // See if this component's site has an IExtenderListService. If it // does, we get our list of extenders from that, not from the container. // IExtenderListService listService = (IExtenderListService)site.GetService(typeof(IExtenderListService)); if (listService != null) { return listService.GetExtenderProviders(); } else { ComponentCollection comps = site.Container.Components; ArrayList exList = null; foreach(IComponent comp in comps) { if (comp is IExtenderProvider) { if (exList == null) { exList = new ArrayList(2); } exList.Add(comp); } } if (exList == null) { return null; } else { IExtenderProvider[] temp = new IExtenderProvider[exList.Count]; exList.CopyTo(temp, 0); return temp; } } }
internal Type ExtenderGetType(IExtenderProvider provider) { return(this.PropertyType); }
/// <devdoc> /// This performs the actual reflection needed to discover /// extender properties. If object caching is supported this /// will maintain a cache of property descriptors on the /// extender provider. Extender properties are actually two /// property descriptors in one. There is a chunk of per-class /// data in a ReflectPropertyDescriptor that defines the /// parameter types and get and set methods of the extended property, /// and there is an ExtendedPropertyDescriptor that combines this /// with an extender provider object to create what looks like a /// normal property. ReflectGetExtendedProperties maintains two /// separate caches for these two sets: a static one for the /// ReflectPropertyDescriptor values that don't change for each /// provider instance, and a per-provider cache that contains /// the ExtendedPropertyDescriptors. /// </devdoc> private static PropertyDescriptor[] ReflectGetExtendedProperties(IExtenderProvider provider) { IDictionary cache = TypeDescriptor.GetCache(provider); PropertyDescriptor[] properties; if (cache != null) { properties = cache[_extenderProviderPropertiesKey] as PropertyDescriptor[]; if (properties != null) { return properties; } } // Our per-instance cache missed. We have never seen this instance of the // extender provider before. See if we can find our class-based // property store. // if (_extendedPropertyCache == null) { lock (_internalSyncObject) { if (_extendedPropertyCache == null) { _extendedPropertyCache = new Hashtable(); } } } Type providerType = provider.GetType(); ReflectPropertyDescriptor[] extendedProperties = (ReflectPropertyDescriptor[])_extendedPropertyCache[providerType]; if (extendedProperties == null) { lock (_internalSyncObject) { extendedProperties = (ReflectPropertyDescriptor[])_extendedPropertyCache[providerType]; // Our class-based property store failed as well, so we need to build up the set of // extended properties here. // if (extendedProperties == null) { AttributeCollection attributes = TypeDescriptor.GetAttributes(providerType); ArrayList extendedList = new ArrayList(attributes.Count); foreach(Attribute attr in attributes) { ProvidePropertyAttribute provideAttr = attr as ProvidePropertyAttribute; if (provideAttr != null) { Type receiverType = GetTypeFromName(provideAttr.ReceiverTypeName); if (receiverType != null) { MethodInfo getMethod = providerType.GetMethod("Get" + provideAttr.PropertyName, new Type[] {receiverType}); if (getMethod != null && !getMethod.IsStatic && getMethod.IsPublic) { MethodInfo setMethod = providerType.GetMethod("Set" + provideAttr.PropertyName, new Type[] {receiverType, getMethod.ReturnType}); if (setMethod != null && (setMethod.IsStatic || !setMethod.IsPublic)) { setMethod = null; } extendedList.Add(new ReflectPropertyDescriptor(providerType, provideAttr.PropertyName, getMethod.ReturnType, receiverType, getMethod, setMethod, null)); } } } } extendedProperties = new ReflectPropertyDescriptor[extendedList.Count]; extendedList.CopyTo(extendedProperties, 0); _extendedPropertyCache[providerType] = extendedProperties; } } } // Now that we have our extended properties we can build up a list of callable properties. These can be // returned to the user. // properties = new PropertyDescriptor[extendedProperties.Length]; for (int idx = 0; idx < extendedProperties.Length; idx++) { Attribute[] attrs = null; IComponent comp = provider as IComponent; if (comp == null || comp.Site == null) { attrs = new Attribute[] {DesignOnlyAttribute.Yes}; } ReflectPropertyDescriptor rpd = extendedProperties[idx]; ExtendedPropertyDescriptor epd = new ExtendedPropertyDescriptor(rpd, rpd.ExtenderGetReceiverType(), provider, attrs); properties[idx] = epd; } if (cache != null) { cache[_extenderProviderPropertiesKey] = properties; } return properties; }
/// <devdoc> /// Creates a new extended property info. Callers can then treat this as /// a standard property. /// </devdoc> public DebugExtendedPropertyDescriptor(DebugReflectPropertyDescriptor extenderInfo, Type receiverType, IExtenderProvider provider) : this(extenderInfo, receiverType, provider, null) { }
internal Type ExtenderGetType(IExtenderProvider provider) => PropertyType;
// This will return true if the given array if extenders is the same // as the set that these stashed properties were created with. // public bool ExtendersMatch(IExtenderProvider[] providers, object instance) { long hash = HashExtenders(providers, instance); return extenderHash == hash; }
internal static ExtenderProvidedPropertyAttribute Create(PropertyDescriptor extenderProperty, Type receiverType, IExtenderProvider provider) { return(new ExtenderProvidedPropertyAttribute { extenderProperty = extenderProperty, receiverType = receiverType, provider = provider }); }
/// <devdoc> /// GetExtenders builds a list of extender providers from /// a collection of components. It validates the extenders /// against any cached collection of extenders in the /// cache. If there is a discrepancy, this will erase /// any cached extender properties from the cache and /// save the updated extender list. If there is no /// discrepancy this will simply return the cached list. /// </devdoc> private static IExtenderProvider[] GetExtenders(ICollection components, object instance, IDictionary cache) { bool newExtenders = false; int extenderCount = 0; IExtenderProvider[] existingExtenders = null; //CanExtend is expensive. We will remember results of CanExtend for the first 64 extenders and using "long canExtend" as a bit vector. // we want to avoid memory allocation as well so we don't use some more sophisticated data structure like an array of booleans UInt64 canExtend = 0; int maxCanExtendResults = 64; // currentExtenders is what we intend to return. If the caller passed us // the return value from IExtenderListService, components will already be // an IExtenderProvider[]. If not, then we must treat components as an // opaque collection. We spend a great deal of energy here to avoid // copying or allocating memory because this method is called every // time a component is asked for its properties. IExtenderProvider[] currentExtenders = components as IExtenderProvider[]; if (cache != null) { existingExtenders = cache[_extenderProviderKey] as IExtenderProvider[]; } if (existingExtenders == null) { newExtenders = true; } int curIdx = 0; int idx = 0; if (currentExtenders != null) { for (curIdx = 0; curIdx < currentExtenders.Length; curIdx++) { if (currentExtenders[curIdx].CanExtend(instance)) { extenderCount++; // Performance:We would like to call CanExtend as little as possible therefore we remember its result if (curIdx < maxCanExtendResults) canExtend |= (UInt64)1 << curIdx; if (!newExtenders && (idx >= existingExtenders.Length || currentExtenders[curIdx] != existingExtenders[idx++])) { newExtenders = true; } } } } else if (components != null) { foreach(object obj in components) { IExtenderProvider prov = obj as IExtenderProvider; if (prov != null && prov.CanExtend(instance)) { extenderCount++; if (curIdx < maxCanExtendResults) canExtend |= (UInt64)1<<curIdx; if (!newExtenders && (idx >= existingExtenders.Length || prov != existingExtenders[idx++])) { newExtenders = true; } } curIdx++; } } if (existingExtenders != null && extenderCount != existingExtenders.Length) { newExtenders = true; } if (newExtenders) { TypeDescriptor.Trace("Extenders : object has new extenders : {0}", instance.GetType().Name); TypeDescriptor.Trace("Extenders : Identified {0} extender providers", extenderCount); if (currentExtenders == null || extenderCount != currentExtenders.Length) { IExtenderProvider[] newExtenderArray = new IExtenderProvider[extenderCount]; curIdx = 0; idx = 0; if (currentExtenders != null && extenderCount > 0) { while(curIdx < currentExtenders.Length) { if ((curIdx < maxCanExtendResults && (canExtend & ((UInt64)1 << curIdx)) != 0 )|| (curIdx >= maxCanExtendResults && currentExtenders[curIdx].CanExtend(instance))) { Debug.Assert(idx < extenderCount, "There are more extenders than we expect"); newExtenderArray[idx++] = currentExtenders[curIdx]; } curIdx++; } Debug.Assert(idx == extenderCount, "Wrong number of extenders"); } else if (extenderCount > 0) { IEnumerator componentEnum = components.GetEnumerator(); while(componentEnum.MoveNext()) { IExtenderProvider p = componentEnum.Current as IExtenderProvider; if (p != null && ((curIdx < maxCanExtendResults && (canExtend & ((UInt64)1 << curIdx)) != 0) || (curIdx >= maxCanExtendResults && p.CanExtend(instance)))) { Debug.Assert(idx < extenderCount, "There are more extenders than we expect"); newExtenderArray[idx++] = p; } curIdx++; } Debug.Assert(idx == extenderCount, "Wrong number of extenders"); } currentExtenders = newExtenderArray; } if (cache != null) { TypeDescriptor.Trace("Extenders : caching extender provider results"); cache[_extenderProviderKey] = currentExtenders; cache.Remove(_extenderPropertiesKey); } } else { currentExtenders = existingExtenders; } return currentExtenders; }
// This is a simple hashing algorithm that attempts to create // a unique number for a given set of extender providers. // private long HashExtenders(IExtenderProvider[] providers, object instance) { long hash = 0; int count = (providers == null ? 0 : providers.Length); for (int i = 0; i < count; i++) { if (providers[i].CanExtend(instance)) { hash += providers[i].GetHashCode(); } } return hash; }