Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / CompMod / System / ComponentModel / ReflectEventDescriptor.cs / 1 / ReflectEventDescriptor.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.ComponentModel { using Microsoft.Win32; using System; using System.Collections; using System.ComponentModel.Design; using System.Diagnostics; using System.Reflection; using System.Security.Permissions; ////// /// [HostProtection(SharedState = true)] internal sealed class ReflectEventDescriptor : EventDescriptor { private static readonly Type[] argsNone = new Type[0]; private static readonly object noDefault = new object(); private Type type; // the delegate type for the event private readonly Type componentClass; // the class of the component this info is for private MethodInfo addMethod; // the method to use when adding an event private MethodInfo removeMethod; // the method to use when removing an event private EventInfo realEvent; // actual event info... may be null private bool filledMethods = false; // did we already call FillMethods() once? ////// ReflectEventDescriptor defines an event. Events are the main way that a user can get /// run-time notifications from a component. /// The ReflectEventDescriptor class takes a component class that the event lives on, /// the event name, the type of the event handling delegate, and various /// attributes for the event. /// Every event has a structure through which it passes it's information. The base /// structure, Event, is empty, and there is a default instance, Event.EMPTY, which /// is usually passed. When addOnXXX is invoked, it needs a pointer to a method /// that takes a source object (the object that fired the event) and a structure /// particular to that event. It also needs a pointer to the instance of the /// object the method should be invoked on. These two things are what composes a /// delegate. An event handler is /// a delegate, and the compiler recognizes a special delegate syntax that makes /// using delegates easy. /// For example, to listen to the click event on a button in class Foo, the /// following code will suffice: /// ////// class Foo { /// Button button1 = new Button(); /// void button1_click(Object sender, Event e) { /// // do something on button1 click. /// } /// public Foo() { /// button1.addOnClick(this.button1_click); /// } /// } ///
/// For an event named XXX, a YYYEvent structure, and a YYYEventHandler delegate, /// a component writer is required to implement two methods of the following /// form: ////// public void addOnXXX(YYYEventHandler handler); /// public void removeOnXXX(YYYEventHandler handler); ///
/// YYYEventHandler should be an event handler declared as ////// public multicast delegate void YYYEventHandler(Object sender, YYYEvent e); ///
/// Note that this event was declared as a multicast delegate. This allows multiple /// listeners on an event. This is not a requirement. /// Various attributes can be passed to the ReflectEventDescriptor, as are described in /// Attribute. /// ReflectEventDescriptors can be obtained by a user programmatically through the /// ComponentManager. ////// This is the main constructor for an ReflectEventDescriptor. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, Attribute[] attributes) : base(name, attributes) { if (componentClass == null) { throw new ArgumentException(SR.GetString(SR.InvalidNullArgument, "componentClass")); } if (type == null || !(typeof(Delegate)).IsAssignableFrom(type)) { throw new ArgumentException(SR.GetString(SR.ErrorInvalidEventType, name)); } Debug.Assert(type.IsSubclassOf(typeof(Delegate)), "Not a valid ReflectEvent: " + componentClass.FullName + "." + name + " " + type.FullName); this.componentClass = componentClass; this.type = type; } public ReflectEventDescriptor(Type componentClass, EventInfo eventInfo) : base(eventInfo.Name, new Attribute[0]) { if (componentClass == null) { throw new ArgumentException(SR.GetString(SR.InvalidNullArgument, "componentClass")); } this.componentClass = componentClass; this.realEvent = eventInfo; } ////// This constructor takes an existing ReflectEventDescriptor and modifies it by merging in the /// passed-in attributes. /// public ReflectEventDescriptor(Type componentType, EventDescriptor oldReflectEventDescriptor, Attribute[] attributes) : base(oldReflectEventDescriptor, attributes) { this.componentClass = componentType; this.type = oldReflectEventDescriptor.EventType; ReflectEventDescriptor desc = oldReflectEventDescriptor as ReflectEventDescriptor; if (desc != null) { this.addMethod = desc.addMethod; this.removeMethod = desc.removeMethod; this.filledMethods = true; } #if DEBUG else if (oldReflectEventDescriptor is DebugReflectEventDescriptor) { this.addMethod = ((DebugReflectEventDescriptor)oldReflectEventDescriptor).addMethod; this.removeMethod = ((DebugReflectEventDescriptor)oldReflectEventDescriptor).removeMethod; this.filledMethods = true; } #endif } ////// Retrieves the type of the component this EventDescriptor is bound to. /// public override Type ComponentType { get { return componentClass; } } ////// Retrieves the type of the delegate for this event. /// public override Type EventType { get { FillMethods(); return type; } } ////// Indicates whether the delegate type for this event is a multicast /// delegate. /// public override bool IsMulticast { get { return(typeof(MulticastDelegate)).IsAssignableFrom(EventType); } } ////// This adds the delegate value as a listener to when this event is fired /// by the component, invoking the addOnXXX method. /// public override void AddEventHandler(object component, Delegate value) { FillMethods(); if (component != null) { ISite site = GetSite(component); IComponentChangeService changeService = 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"); } if (changeService != null) { try { changeService.OnComponentChanging(component, this); } catch (CheckoutException coEx) { if (coEx == CheckoutException.Canceled) { return; } throw coEx; } } bool shadowed = false; if (site != null && site.DesignMode) { // Events are final, so just check the class if (EventType != value.GetType()) { throw new ArgumentException(SR.GetString(SR.ErrorInvalidEventHandler, Name)); } IDictionaryService dict = (IDictionaryService)site.GetService(typeof(IDictionaryService)); Debug.Assert(!CompModSwitches.CommonDesignerServices.Enabled || dict != null, "IDictionaryService not found"); if (dict != null) { Delegate eventdesc = (Delegate)dict.GetValue(this); eventdesc = Delegate.Combine(eventdesc, value); dict.SetValue(this, eventdesc); shadowed = true; } } if (!shadowed) { addMethod.Invoke(component, new object[] { value}); } // Now notify the change service that the change was successful. // if (changeService != null) { changeService.OnComponentChanged(component, this, null, value); } } } //// // protected override void FillAttributes(IList attributes) { // // The order that we fill in attributes is critical. The list of attributes will be // filtered so that matching attributes at the end of the list replace earlier matches // (last one in wins). Therefore, the two categories of attributes we add must be // added as follows: // // 1. Attributes of the event, from base class to most derived. This way // derived class attributes replace base class attributes. // // 2. Attributes from our base MemberDescriptor. While this seems opposite of what // we want, MemberDescriptor only has attributes if someone passed in a new // set in the constructor. Therefore, these attributes always // supercede existing values. // FillMethods(); Debug.Assert(componentClass != null, "Must have a component class for FilterAttributes"); if (realEvent != null) { FillEventInfoAttribute(realEvent, attributes); } else { Debug.Assert(removeMethod != null, "Null remove method for " + Name); FillSingleMethodAttribute(removeMethod, attributes); Debug.Assert(addMethod != null, "Null remove method for " + Name); FillSingleMethodAttribute(addMethod, attributes); } // Include the base attributes. These override all attributes on the actual // property, so we want to add them last. // base.FillAttributes(attributes); } private void FillEventInfoAttribute(EventInfo realEventInfo, IList attributes) { string eventName = realEventInfo.Name; BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; Type currentReflectType = realEventInfo.ReflectedType; Debug.Assert(currentReflectType != null, "currentReflectType cannot be null"); int depth = 0; // First, calculate the depth of the object hierarchy. We do this so we can do a single // object create for an array of attributes. // while(currentReflectType != typeof(object)) { depth++; currentReflectType = currentReflectType.BaseType; } if (depth > 0) { // Now build up an array in reverse order // currentReflectType = realEventInfo.ReflectedType; Attribute[][] attributeStack = new Attribute[depth][]; while(currentReflectType != typeof(object)) { // Fill in our member info so we can get at the custom attributes. // MemberInfo memberInfo = currentReflectType.GetEvent(eventName, bindingFlags); // Get custom attributes for the member info. // if (memberInfo != null) { attributeStack[--depth] = ReflectTypeDescriptionProvider.ReflectGetAttributes(memberInfo); } // Ready for the next loop iteration. // currentReflectType = currentReflectType.BaseType; } // Now trawl the attribute stack so that we add attributes // from base class to most derived. // foreach(Attribute[] attributeArray in attributeStack) { if (attributeArray != null) { foreach(Attribute attr in attributeArray) { attributes.Add(attr); } } } } } ///// Adds in custom attributes found on either the AddOn or RemoveOn method... // ///// This fills the get and set method fields of the event info. It is shared /// by the various constructors. /// private void FillMethods() { if (filledMethods) return; if (realEvent != null) { addMethod = realEvent.GetAddMethod(); removeMethod = realEvent.GetRemoveMethod(); EventInfo defined = null; if (addMethod == null || removeMethod == null) { Type start = componentClass.BaseType; while (start != null && start != typeof(object)) { BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; EventInfo test = start.GetEvent(realEvent.Name, bindingFlags); if (test.GetAddMethod() != null) { defined = test; break; } } } if (defined != null) { addMethod = defined.GetAddMethod(); removeMethod = defined.GetRemoveMethod(); type = defined.EventHandlerType; } else { type = realEvent.EventHandlerType; } } else { // first, try to get the eventInfo... // realEvent = this.componentClass.GetEvent(Name); if (realEvent != null) { // if we got one, just recurse and return. // FillMethods(); return; } Type[] argsType = new Type[] {type}; addMethod = FindMethod(componentClass, "AddOn" + Name, argsType, typeof(void)); removeMethod = FindMethod(componentClass, "RemoveOn" + Name, argsType, typeof(void)); if (addMethod == null || removeMethod == null) { Debug.Fail("Missing event accessors for " + componentClass.FullName + "." + Name); throw new ArgumentException(SR.GetString(SR.ErrorMissingEventAccessors, Name)); } } filledMethods = true; } private void FillSingleMethodAttribute(MethodInfo realMethodInfo, IList attributes) { string methodName = realMethodInfo.Name; BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; Type currentReflectType = realMethodInfo.ReflectedType; Debug.Assert(currentReflectType != null, "currentReflectType cannot be null"); // First, calculate the depth of the object hierarchy. We do this so we can do a single // object create for an array of attributes. // int depth = 0; while(currentReflectType != null && currentReflectType != typeof(object)) { depth++; currentReflectType = currentReflectType.BaseType; } if (depth > 0) { // Now build up an array in reverse order // currentReflectType = realMethodInfo.ReflectedType; Attribute[][] attributeStack = new Attribute[depth][]; while(currentReflectType != null && currentReflectType != typeof(object)) { // Fill in our member info so we can get at the custom attributes. // MemberInfo memberInfo = currentReflectType.GetMethod(methodName, bindingFlags); // Get custom attributes for the member info. // if (memberInfo != null) { attributeStack[--depth] = ReflectTypeDescriptionProvider.ReflectGetAttributes(memberInfo); } // Ready for the next loop iteration. // currentReflectType = currentReflectType.BaseType; } // Now trawl the attribute stack so that we add attributes // from base class to most derived. // foreach(Attribute[] attributeArray in attributeStack) { if (attributeArray != null) { foreach(Attribute attr in attributeArray) { attributes.Add(attr); } } } } } ////// This will remove the delegate value from the event chain so that /// it no longer gets events from this component. /// public override void RemoveEventHandler(object component, Delegate value) { FillMethods(); if (component != null) { ISite site = GetSite(component); IComponentChangeService changeService = 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"); } if (changeService != null) { try { changeService.OnComponentChanging(component, this); } catch (CheckoutException coEx) { if (coEx == CheckoutException.Canceled) { return; } throw coEx; } } bool shadowed = false; if (site != null && site.DesignMode) { IDictionaryService dict = (IDictionaryService)site.GetService(typeof(IDictionaryService)); Debug.Assert(!CompModSwitches.CommonDesignerServices.Enabled || dict != null, "IDictionaryService not found"); if (dict != null) { Delegate del = (Delegate)dict.GetValue(this); del = Delegate.Remove(del, value); dict.SetValue(this, del); shadowed = true; } } if (!shadowed) { removeMethod.Invoke(component, new object[] { value}); } // Now notify the change service that the change was successful. // if (changeService != null) { changeService.OnComponentChanged(component, this, null, value); } } } /* The following code has been removed to fix FXCOP violations. its left here incase it needs to be resurected. This code is from ReflectEventDescriptor class ////// This is a shortcut main constructor for an ReflectEventDescriptor with one attribute. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, MethodInfo addMethod, MethodInfo removeMethod) : this(componentClass, name, type, (Attribute[]) null) { this.addMethod = addMethod; this.removeMethod = removeMethod; this.filledMethods = true; } ////// This is a shortcut main constructor for an ReflectEventDescriptor with one attribute. /// public ReflectEventDescriptor(Type componentClass, string name, Type type) : this(componentClass, name, type, (Attribute[]) null) { } ////// This is a shortcut main constructor for an ReflectEventDescriptor with two attributes. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, Attribute a1) : this(componentClass, name, type, new Attribute[] {a1}) { } ////// This is a shortcut main constructor for an ReflectEventDescriptor with two attributes. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, Attribute a1, Attribute a2) : this(componentClass, name, type, new Attribute[] {a1, a2}) { } ////// This is a shortcut main constructor for an ReflectEventDescriptor with three attributes. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, Attribute a1, Attribute a2, Attribute a3) : this(componentClass, name, type, new Attribute[] {a1, a2, a3}) { } ////// This is a shortcut main constructor for an ReflectEventDescriptor with four attributes. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, Attribute a1, Attribute a2, Attribute a3, Attribute a4) : this(componentClass, name, type, new Attribute[] {a1, a2, a3, a4}) { } ////// This constructor takes an existing ReflectEventDescriptor and modifies it by merging in the /// passed-in attributes. /// public ReflectEventDescriptor(EventDescriptor oldReflectEventDescriptor, Attribute[] attributes) : this(oldReflectEventDescriptor.ComponentType, oldReflectEventDescriptor, attributes) { } ////// This is a shortcut constructor that takes an existing ReflectEventDescriptor and one attribute to /// merge in. /// public ReflectEventDescriptor(EventDescriptor oldReflectEventDescriptor, Attribute a1) : this(oldReflectEventDescriptor, new Attribute[] { a1}) { } ////// This is a shortcut constructor that takes an existing ReflectEventDescriptor and two attributes to /// merge in. /// public ReflectEventDescriptor(EventDescriptor oldReflectEventDescriptor, Attribute a1, Attribute a2) : this(oldReflectEventDescriptor, new Attribute[] { a1,a2}) { } ////// This is a shortcut constructor that takes an existing ReflectEventDescriptor and three attributes to /// merge in. /// public ReflectEventDescriptor(EventDescriptor oldReflectEventDescriptor, Attribute a1, Attribute a2, Attribute a3) : this(oldReflectEventDescriptor, new Attribute[] { a1,a2,a3}) { } ////// This is a shortcut constructor that takes an existing ReflectEventDescriptor and four attributes to /// merge in. /// public ReflectEventDescriptor(EventDescriptor oldReflectEventDescriptor, Attribute a1, Attribute a2, Attribute a3, Attribute a4) : this(oldReflectEventDescriptor, new Attribute[] { a1,a2,a3,a4}) { } */ } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.ComponentModel { using Microsoft.Win32; using System; using System.Collections; using System.ComponentModel.Design; using System.Diagnostics; using System.Reflection; using System.Security.Permissions; ////// /// [HostProtection(SharedState = true)] internal sealed class ReflectEventDescriptor : EventDescriptor { private static readonly Type[] argsNone = new Type[0]; private static readonly object noDefault = new object(); private Type type; // the delegate type for the event private readonly Type componentClass; // the class of the component this info is for private MethodInfo addMethod; // the method to use when adding an event private MethodInfo removeMethod; // the method to use when removing an event private EventInfo realEvent; // actual event info... may be null private bool filledMethods = false; // did we already call FillMethods() once? ////// ReflectEventDescriptor defines an event. Events are the main way that a user can get /// run-time notifications from a component. /// The ReflectEventDescriptor class takes a component class that the event lives on, /// the event name, the type of the event handling delegate, and various /// attributes for the event. /// Every event has a structure through which it passes it's information. The base /// structure, Event, is empty, and there is a default instance, Event.EMPTY, which /// is usually passed. When addOnXXX is invoked, it needs a pointer to a method /// that takes a source object (the object that fired the event) and a structure /// particular to that event. It also needs a pointer to the instance of the /// object the method should be invoked on. These two things are what composes a /// delegate. An event handler is /// a delegate, and the compiler recognizes a special delegate syntax that makes /// using delegates easy. /// For example, to listen to the click event on a button in class Foo, the /// following code will suffice: /// ////// class Foo { /// Button button1 = new Button(); /// void button1_click(Object sender, Event e) { /// // do something on button1 click. /// } /// public Foo() { /// button1.addOnClick(this.button1_click); /// } /// } ///
/// For an event named XXX, a YYYEvent structure, and a YYYEventHandler delegate, /// a component writer is required to implement two methods of the following /// form: ////// public void addOnXXX(YYYEventHandler handler); /// public void removeOnXXX(YYYEventHandler handler); ///
/// YYYEventHandler should be an event handler declared as ////// public multicast delegate void YYYEventHandler(Object sender, YYYEvent e); ///
/// Note that this event was declared as a multicast delegate. This allows multiple /// listeners on an event. This is not a requirement. /// Various attributes can be passed to the ReflectEventDescriptor, as are described in /// Attribute. /// ReflectEventDescriptors can be obtained by a user programmatically through the /// ComponentManager. ////// This is the main constructor for an ReflectEventDescriptor. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, Attribute[] attributes) : base(name, attributes) { if (componentClass == null) { throw new ArgumentException(SR.GetString(SR.InvalidNullArgument, "componentClass")); } if (type == null || !(typeof(Delegate)).IsAssignableFrom(type)) { throw new ArgumentException(SR.GetString(SR.ErrorInvalidEventType, name)); } Debug.Assert(type.IsSubclassOf(typeof(Delegate)), "Not a valid ReflectEvent: " + componentClass.FullName + "." + name + " " + type.FullName); this.componentClass = componentClass; this.type = type; } public ReflectEventDescriptor(Type componentClass, EventInfo eventInfo) : base(eventInfo.Name, new Attribute[0]) { if (componentClass == null) { throw new ArgumentException(SR.GetString(SR.InvalidNullArgument, "componentClass")); } this.componentClass = componentClass; this.realEvent = eventInfo; } ////// This constructor takes an existing ReflectEventDescriptor and modifies it by merging in the /// passed-in attributes. /// public ReflectEventDescriptor(Type componentType, EventDescriptor oldReflectEventDescriptor, Attribute[] attributes) : base(oldReflectEventDescriptor, attributes) { this.componentClass = componentType; this.type = oldReflectEventDescriptor.EventType; ReflectEventDescriptor desc = oldReflectEventDescriptor as ReflectEventDescriptor; if (desc != null) { this.addMethod = desc.addMethod; this.removeMethod = desc.removeMethod; this.filledMethods = true; } #if DEBUG else if (oldReflectEventDescriptor is DebugReflectEventDescriptor) { this.addMethod = ((DebugReflectEventDescriptor)oldReflectEventDescriptor).addMethod; this.removeMethod = ((DebugReflectEventDescriptor)oldReflectEventDescriptor).removeMethod; this.filledMethods = true; } #endif } ////// Retrieves the type of the component this EventDescriptor is bound to. /// public override Type ComponentType { get { return componentClass; } } ////// Retrieves the type of the delegate for this event. /// public override Type EventType { get { FillMethods(); return type; } } ////// Indicates whether the delegate type for this event is a multicast /// delegate. /// public override bool IsMulticast { get { return(typeof(MulticastDelegate)).IsAssignableFrom(EventType); } } ////// This adds the delegate value as a listener to when this event is fired /// by the component, invoking the addOnXXX method. /// public override void AddEventHandler(object component, Delegate value) { FillMethods(); if (component != null) { ISite site = GetSite(component); IComponentChangeService changeService = 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"); } if (changeService != null) { try { changeService.OnComponentChanging(component, this); } catch (CheckoutException coEx) { if (coEx == CheckoutException.Canceled) { return; } throw coEx; } } bool shadowed = false; if (site != null && site.DesignMode) { // Events are final, so just check the class if (EventType != value.GetType()) { throw new ArgumentException(SR.GetString(SR.ErrorInvalidEventHandler, Name)); } IDictionaryService dict = (IDictionaryService)site.GetService(typeof(IDictionaryService)); Debug.Assert(!CompModSwitches.CommonDesignerServices.Enabled || dict != null, "IDictionaryService not found"); if (dict != null) { Delegate eventdesc = (Delegate)dict.GetValue(this); eventdesc = Delegate.Combine(eventdesc, value); dict.SetValue(this, eventdesc); shadowed = true; } } if (!shadowed) { addMethod.Invoke(component, new object[] { value}); } // Now notify the change service that the change was successful. // if (changeService != null) { changeService.OnComponentChanged(component, this, null, value); } } } //// // protected override void FillAttributes(IList attributes) { // // The order that we fill in attributes is critical. The list of attributes will be // filtered so that matching attributes at the end of the list replace earlier matches // (last one in wins). Therefore, the two categories of attributes we add must be // added as follows: // // 1. Attributes of the event, from base class to most derived. This way // derived class attributes replace base class attributes. // // 2. Attributes from our base MemberDescriptor. While this seems opposite of what // we want, MemberDescriptor only has attributes if someone passed in a new // set in the constructor. Therefore, these attributes always // supercede existing values. // FillMethods(); Debug.Assert(componentClass != null, "Must have a component class for FilterAttributes"); if (realEvent != null) { FillEventInfoAttribute(realEvent, attributes); } else { Debug.Assert(removeMethod != null, "Null remove method for " + Name); FillSingleMethodAttribute(removeMethod, attributes); Debug.Assert(addMethod != null, "Null remove method for " + Name); FillSingleMethodAttribute(addMethod, attributes); } // Include the base attributes. These override all attributes on the actual // property, so we want to add them last. // base.FillAttributes(attributes); } private void FillEventInfoAttribute(EventInfo realEventInfo, IList attributes) { string eventName = realEventInfo.Name; BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; Type currentReflectType = realEventInfo.ReflectedType; Debug.Assert(currentReflectType != null, "currentReflectType cannot be null"); int depth = 0; // First, calculate the depth of the object hierarchy. We do this so we can do a single // object create for an array of attributes. // while(currentReflectType != typeof(object)) { depth++; currentReflectType = currentReflectType.BaseType; } if (depth > 0) { // Now build up an array in reverse order // currentReflectType = realEventInfo.ReflectedType; Attribute[][] attributeStack = new Attribute[depth][]; while(currentReflectType != typeof(object)) { // Fill in our member info so we can get at the custom attributes. // MemberInfo memberInfo = currentReflectType.GetEvent(eventName, bindingFlags); // Get custom attributes for the member info. // if (memberInfo != null) { attributeStack[--depth] = ReflectTypeDescriptionProvider.ReflectGetAttributes(memberInfo); } // Ready for the next loop iteration. // currentReflectType = currentReflectType.BaseType; } // Now trawl the attribute stack so that we add attributes // from base class to most derived. // foreach(Attribute[] attributeArray in attributeStack) { if (attributeArray != null) { foreach(Attribute attr in attributeArray) { attributes.Add(attr); } } } } } ///// Adds in custom attributes found on either the AddOn or RemoveOn method... // ///// This fills the get and set method fields of the event info. It is shared /// by the various constructors. /// private void FillMethods() { if (filledMethods) return; if (realEvent != null) { addMethod = realEvent.GetAddMethod(); removeMethod = realEvent.GetRemoveMethod(); EventInfo defined = null; if (addMethod == null || removeMethod == null) { Type start = componentClass.BaseType; while (start != null && start != typeof(object)) { BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; EventInfo test = start.GetEvent(realEvent.Name, bindingFlags); if (test.GetAddMethod() != null) { defined = test; break; } } } if (defined != null) { addMethod = defined.GetAddMethod(); removeMethod = defined.GetRemoveMethod(); type = defined.EventHandlerType; } else { type = realEvent.EventHandlerType; } } else { // first, try to get the eventInfo... // realEvent = this.componentClass.GetEvent(Name); if (realEvent != null) { // if we got one, just recurse and return. // FillMethods(); return; } Type[] argsType = new Type[] {type}; addMethod = FindMethod(componentClass, "AddOn" + Name, argsType, typeof(void)); removeMethod = FindMethod(componentClass, "RemoveOn" + Name, argsType, typeof(void)); if (addMethod == null || removeMethod == null) { Debug.Fail("Missing event accessors for " + componentClass.FullName + "." + Name); throw new ArgumentException(SR.GetString(SR.ErrorMissingEventAccessors, Name)); } } filledMethods = true; } private void FillSingleMethodAttribute(MethodInfo realMethodInfo, IList attributes) { string methodName = realMethodInfo.Name; BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; Type currentReflectType = realMethodInfo.ReflectedType; Debug.Assert(currentReflectType != null, "currentReflectType cannot be null"); // First, calculate the depth of the object hierarchy. We do this so we can do a single // object create for an array of attributes. // int depth = 0; while(currentReflectType != null && currentReflectType != typeof(object)) { depth++; currentReflectType = currentReflectType.BaseType; } if (depth > 0) { // Now build up an array in reverse order // currentReflectType = realMethodInfo.ReflectedType; Attribute[][] attributeStack = new Attribute[depth][]; while(currentReflectType != null && currentReflectType != typeof(object)) { // Fill in our member info so we can get at the custom attributes. // MemberInfo memberInfo = currentReflectType.GetMethod(methodName, bindingFlags); // Get custom attributes for the member info. // if (memberInfo != null) { attributeStack[--depth] = ReflectTypeDescriptionProvider.ReflectGetAttributes(memberInfo); } // Ready for the next loop iteration. // currentReflectType = currentReflectType.BaseType; } // Now trawl the attribute stack so that we add attributes // from base class to most derived. // foreach(Attribute[] attributeArray in attributeStack) { if (attributeArray != null) { foreach(Attribute attr in attributeArray) { attributes.Add(attr); } } } } } ////// This will remove the delegate value from the event chain so that /// it no longer gets events from this component. /// public override void RemoveEventHandler(object component, Delegate value) { FillMethods(); if (component != null) { ISite site = GetSite(component); IComponentChangeService changeService = 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"); } if (changeService != null) { try { changeService.OnComponentChanging(component, this); } catch (CheckoutException coEx) { if (coEx == CheckoutException.Canceled) { return; } throw coEx; } } bool shadowed = false; if (site != null && site.DesignMode) { IDictionaryService dict = (IDictionaryService)site.GetService(typeof(IDictionaryService)); Debug.Assert(!CompModSwitches.CommonDesignerServices.Enabled || dict != null, "IDictionaryService not found"); if (dict != null) { Delegate del = (Delegate)dict.GetValue(this); del = Delegate.Remove(del, value); dict.SetValue(this, del); shadowed = true; } } if (!shadowed) { removeMethod.Invoke(component, new object[] { value}); } // Now notify the change service that the change was successful. // if (changeService != null) { changeService.OnComponentChanged(component, this, null, value); } } } /* The following code has been removed to fix FXCOP violations. its left here incase it needs to be resurected. This code is from ReflectEventDescriptor class ////// This is a shortcut main constructor for an ReflectEventDescriptor with one attribute. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, MethodInfo addMethod, MethodInfo removeMethod) : this(componentClass, name, type, (Attribute[]) null) { this.addMethod = addMethod; this.removeMethod = removeMethod; this.filledMethods = true; } ////// This is a shortcut main constructor for an ReflectEventDescriptor with one attribute. /// public ReflectEventDescriptor(Type componentClass, string name, Type type) : this(componentClass, name, type, (Attribute[]) null) { } ////// This is a shortcut main constructor for an ReflectEventDescriptor with two attributes. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, Attribute a1) : this(componentClass, name, type, new Attribute[] {a1}) { } ////// This is a shortcut main constructor for an ReflectEventDescriptor with two attributes. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, Attribute a1, Attribute a2) : this(componentClass, name, type, new Attribute[] {a1, a2}) { } ////// This is a shortcut main constructor for an ReflectEventDescriptor with three attributes. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, Attribute a1, Attribute a2, Attribute a3) : this(componentClass, name, type, new Attribute[] {a1, a2, a3}) { } ////// This is a shortcut main constructor for an ReflectEventDescriptor with four attributes. /// public ReflectEventDescriptor(Type componentClass, string name, Type type, Attribute a1, Attribute a2, Attribute a3, Attribute a4) : this(componentClass, name, type, new Attribute[] {a1, a2, a3, a4}) { } ////// This constructor takes an existing ReflectEventDescriptor and modifies it by merging in the /// passed-in attributes. /// public ReflectEventDescriptor(EventDescriptor oldReflectEventDescriptor, Attribute[] attributes) : this(oldReflectEventDescriptor.ComponentType, oldReflectEventDescriptor, attributes) { } ////// This is a shortcut constructor that takes an existing ReflectEventDescriptor and one attribute to /// merge in. /// public ReflectEventDescriptor(EventDescriptor oldReflectEventDescriptor, Attribute a1) : this(oldReflectEventDescriptor, new Attribute[] { a1}) { } ////// This is a shortcut constructor that takes an existing ReflectEventDescriptor and two attributes to /// merge in. /// public ReflectEventDescriptor(EventDescriptor oldReflectEventDescriptor, Attribute a1, Attribute a2) : this(oldReflectEventDescriptor, new Attribute[] { a1,a2}) { } ////// This is a shortcut constructor that takes an existing ReflectEventDescriptor and three attributes to /// merge in. /// public ReflectEventDescriptor(EventDescriptor oldReflectEventDescriptor, Attribute a1, Attribute a2, Attribute a3) : this(oldReflectEventDescriptor, new Attribute[] { a1,a2,a3}) { } ////// This is a shortcut constructor that takes an existing ReflectEventDescriptor and four attributes to /// merge in. /// public ReflectEventDescriptor(EventDescriptor oldReflectEventDescriptor, Attribute a1, Attribute a2, Attribute a3, Attribute a4) : this(oldReflectEventDescriptor, new Attribute[] { a1,a2,a3,a4}) { } */ } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WindowsNonControl.cs
- FormsAuthenticationUserCollection.cs
- Variable.cs
- ServiceProviders.cs
- PropertyValueUIItem.cs
- TextEditorTyping.cs
- PenLineJoinValidation.cs
- ExceptionHandler.cs
- WebSysDefaultValueAttribute.cs
- Vector3D.cs
- SqlRowUpdatedEvent.cs
- LoginView.cs
- DifferencingCollection.cs
- OracleEncoding.cs
- IDReferencePropertyAttribute.cs
- ListContractAdapter.cs
- DataGridViewCellLinkedList.cs
- Closure.cs
- ElementAtQueryOperator.cs
- Literal.cs
- Rectangle.cs
- Int16Converter.cs
- IisTraceWebEventProvider.cs
- NameValueSectionHandler.cs
- LifetimeServices.cs
- SqlSupersetValidator.cs
- RectangleConverter.cs
- IDReferencePropertyAttribute.cs
- GridItemPattern.cs
- UriGenerator.cs
- ImageBrush.cs
- BackoffTimeoutHelper.cs
- IPHostEntry.cs
- RegexStringValidatorAttribute.cs
- DPAPIProtectedConfigurationProvider.cs
- FileNameEditor.cs
- Parsers.cs
- LicenseManager.cs
- SerialPort.cs
- HyperLink.cs
- DtrList.cs
- XmlSchemaExternal.cs
- MsmqOutputChannel.cs
- ThicknessConverter.cs
- DecimalAnimationUsingKeyFrames.cs
- CodeChecksumPragma.cs
- DictionaryEntry.cs
- WindowsListViewScroll.cs
- CompiledQueryCacheKey.cs
- PrintPreviewDialog.cs
- RadioButton.cs
- ToolStripOverflowButton.cs
- InkPresenterAutomationPeer.cs
- EastAsianLunisolarCalendar.cs
- WindowsToolbarItemAsMenuItem.cs
- OrderedDictionary.cs
- LinkButton.cs
- DBSchemaRow.cs
- MembershipValidatePasswordEventArgs.cs
- ConfigurationManagerHelper.cs
- MSHTMLHost.cs
- NotCondition.cs
- FragmentQuery.cs
- NameSpaceEvent.cs
- CopyNodeSetAction.cs
- WrapPanel.cs
- WebConfigurationHostFileChange.cs
- ErrorHandlerModule.cs
- UIAgentInitializationException.cs
- DataStreams.cs
- SizeAnimationBase.cs
- ListParagraph.cs
- SqlDelegatedTransaction.cs
- _TimerThread.cs
- OracleNumber.cs
- ColumnReorderedEventArgs.cs
- Identity.cs
- Application.cs
- TraceSwitch.cs
- HostingEnvironmentException.cs
- CommandSet.cs
- TransactionScope.cs
- DataGridPageChangedEventArgs.cs
- XpsException.cs
- FocusWithinProperty.cs
- HostingEnvironment.cs
- DynamicPropertyReader.cs
- GregorianCalendar.cs
- InvalidTimeZoneException.cs
- Formatter.cs
- TimeSpanConverter.cs
- OutputCacheProfileCollection.cs
- IgnorePropertiesAttribute.cs
- Bidi.cs
- Comparer.cs
- ProtocolsConfigurationEntry.cs
- HttpContextServiceHost.cs
- ThreadTrace.cs
- TraceContextRecord.cs
- FileDialog.cs