Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Base / System / ComponentModel / DependencyPropertyDescriptor.cs / 1 / DependencyPropertyDescriptor.cs
using MS.Internal.ComponentModel; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Reflection; using System.Text; using System.Security; using System.Windows; #pragma warning disable 1634, 1691 // suppressing PreSharp warnings namespace System.ComponentModel { ////// This is a wrapper property descriptor that offers a merged API of /// both CLR and DependencyProperty features. To use it, call its /// static FromProperty method passing a PropertyDescriptor. The /// API degrades gracefully if the property descriptor passed does /// not represent a dependency property. /// public sealed class DependencyPropertyDescriptor : PropertyDescriptor { //------------------------------------------------------ // // Constructors // //----------------------------------------------------- #region Constructors ////// Creates a new dependency property descriptor. A note on perf: We don't /// pass the property descriptor down as the default member descriptor here. Doing /// so gets the attributes off of the property descriptor, which can be costly if they /// haven't been accessed yet. Instead, we wait until someone needs to access our /// Attributes property and demand create the attributes at that time. /// private DependencyPropertyDescriptor(PropertyDescriptor property, string name, Type componentType, DependencyProperty dp, bool isAttached) : base(name, null) { Debug.Assert(property != null || !isAttached, "Demand-load of property descriptor is only supported for direct properties"); _property = property; _componentType = componentType; _dp = dp; _isAttached = isAttached; _metadata = _dp.GetMetadata(componentType); } #endregion Constructors //----------------------------------------------------- // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Static method that returns a DependencyPropertyDescriptor from a PropertyDescriptor. /// public static DependencyPropertyDescriptor FromProperty(PropertyDescriptor property) { if (property == null) throw new ArgumentNullException("property"); DependencyPropertyDescriptor dpd; bool found; lock(_cache) { found = _cache.TryGetValue(property, out dpd); } if (found) { return dpd; } // Locate the dependency property. We do this a fast way // by searching for InternalPropertyDescriptor, and a slow // way, by looking for an attribute. The fast way works unless // someone has added another layer of metadata overrides to // TypeDescriptor. DependencyProperty dp = null; bool isAttached = false; DependencyObjectPropertyDescriptor idpd = property as DependencyObjectPropertyDescriptor; if (idpd != null) { dp = idpd.DependencyProperty; isAttached = idpd.IsAttached; } else { #pragma warning suppress 6506 // property is obviously not null DependencyPropertyAttribute dpa = property.Attributes[typeof(DependencyPropertyAttribute)] as DependencyPropertyAttribute; if (dpa != null) { dp = dpa.DependencyProperty; isAttached = dpa.IsAttached; } } if (dp != null) { dpd = new DependencyPropertyDescriptor(property, property.Name, property.ComponentType, dp, isAttached); lock(_cache) { _cache[property] = dpd; } } return dpd; } ////// Static method that returns a DependencyPropertyDescriptor from a DependencyProperty. The /// DependencyProperty may refer to either a direct or attached property. The targetType is the /// type of object to associate with the property: either the owner type for a direct property /// or the type of object to attach to for an attached property. /// public static DependencyPropertyDescriptor FromProperty(DependencyProperty dependencyProperty, Type targetType) { if (dependencyProperty == null) throw new ArgumentNullException("dependencyProperty"); if (targetType == null) throw new ArgumentNullException("targetType"); // We have a different codepath here for attached and direct // properties. For direct properties, we route through Type // Descriptor because we need the underlying CLR property descriptor // to create our wrapped property. For attached properties, all we // need is the dp and the object type and we can create an attached // property descriptor based on that. We must special case attached // properties here because TypeDescriptor will only return attached // properties for instances, not types. DependencyPropertyDescriptor dpd = null; DependencyPropertyKind dpKind = DependencyObjectProvider.GetDependencyPropertyKind(dependencyProperty, targetType); if (dpKind.IsDirect) { // For direct properties we don't want to get the property descriptor // yet because it is very expensive. Delay it until needed. lock(_cache) { _cache.TryGetValue(dependencyProperty, out dpd); } if (dpd == null) { // Create a new DPD based on the type information we have. It // will fill in the property descriptor by calling TypeDescriptor // when needed. dpd = new DependencyPropertyDescriptor(null, dependencyProperty.Name, targetType, dependencyProperty, false); lock(_cache) { _cache[dependencyProperty] = dpd; } } } else if (!dpKind.IsInternal) { // If it isn't a direct property, we treat it as attached unless it is internal. // We should never release internal properties to the user PropertyDescriptor prop = DependencyObjectProvider.GetAttachedPropertyDescriptor(dependencyProperty, targetType); if (prop != null) { dpd = FromProperty(prop); } } return dpd; } ////// Static method that returns a DependencyPropertyDescriptor for a given property name. /// The name may refer to a direct or attached property. OwnerType is the type of /// object that owns the property definition. TargetType is the type of object you wish /// to set the property for. For direct properties, they are the same type. For attached /// properties they usually differ. /// public static DependencyPropertyDescriptor FromName(string name, Type ownerType, Type targetType) { if (name == null) throw new ArgumentNullException("name"); if (ownerType == null) throw new ArgumentNullException("ownerType"); if (targetType == null) throw new ArgumentNullException("targetType"); DependencyProperty dp = DependencyProperty.FromName(name, ownerType); if (dp != null) { return FromProperty(dp, targetType); } return null; } ////// Object.Equals override /// public override bool Equals(object obj) { DependencyPropertyDescriptor dp = obj as DependencyPropertyDescriptor; if (dp != null && dp._dp == _dp && dp._componentType == _componentType) { return true; } return false; } ////// Object.GetHashCode override /// public override int GetHashCode() { return _dp.GetHashCode() ^ _componentType.GetHashCode(); } ////// Object.ToString override /// public override string ToString() { return Name; } // // The following methods simply route to the underlying property descriptor. // ////// When overridden in a derived class, indicates whether /// the property's value can be reset to a default state. /// public override bool CanResetValue(object component) { return Property.CanResetValue(component); } ////// When overridden in a derived class, gets the current /// value of the property on a component. /// public override object GetValue(object component) { return Property.GetValue(component); } ////// When overridden in a derived class, resets the /// value for this property of the component. /// public override void ResetValue(object component) { Property.ResetValue(component); } ////// When overridden in a derived class, sets the value of /// the component to a different value. /// public override void SetValue(object component, object value) { Property.SetValue(component, value); } ////// When overridden in a derived class, indicates whether the /// value of this property needs to be persisted. /// public override bool ShouldSerializeValue(object component) { return Property.ShouldSerializeValue(component); } ////// Allows interested objects to be notified when this property changes. /// public override void AddValueChanged(object component, EventHandler handler) { Property.AddValueChanged(component, handler); } ////// Allows interested objects to be notified when this property changes. /// public override void RemoveValueChanged(object component, EventHandler handler) { Property.RemoveValueChanged(component, handler); } ////// Retrieves the properties /// public override PropertyDescriptorCollection GetChildProperties(object instance, Attribute[] filter) { return Property.GetChildProperties(instance, filter); } ////// Gets an editor of the specified type. /// public override object GetEditor(Type editorBaseType) { return Property.GetEditor(editorBaseType); } #endregion Public Methods //------------------------------------------------------ // // Public Properties // //----------------------------------------------------- #region Public Properties ////// Returns the raw dependency property, or null if the property /// this wraps is not a dependency property. /// public DependencyProperty DependencyProperty { get { return _dp; } } ////// True if the dependency property is being attached to the target type. /// public bool IsAttached { get { return _isAttached; } } ////// The property metadata for the dependency property. This can be null if there is /// no metadata or if there is no dependency property. Values contained in property /// metadata that have matching concepts in CLR attributes are re-exposed as attributes /// in the property descriptor's Attributes collection. /// public PropertyMetadata Metadata { get { return _metadata; } } // // The following properties simply route to the underlying property descriptor. // ////// When overridden in a derived class, gets the type of the /// component this property /// is bound to. /// public override Type ComponentType { get { return _componentType; } } ////// When overridden in a derived class, gets a value /// indicating whether this property is read-only. /// public override bool IsReadOnly { get { return Property.IsReadOnly; } } ////// When overridden in a derived class, /// gets the type of the property. /// public override Type PropertyType { get { return _dp.PropertyType; } } ////// Gets the collection of attributes for this member. /// public override AttributeCollection Attributes { get { return Property.Attributes; } } ////// Gets the name of the category that the /// member belongs to, as specified in the CategoryAttribute. /// public override string Category { get { return Property.Category; } } ////// Gets the description of /// the member as specified in the DescriptionAttribute. /// public override string Description { get { return Property.Description; } } ////// Determines whether this member should be set only at /// design time as specified in the DesignOnlyAttribute. /// public override bool DesignTimeOnly { get { return Property.DesignTimeOnly; } } ////// Gets the name that can be displayed in a window like a /// properties window. /// public override string DisplayName { get { return Property.DisplayName; } } ////// Gets the type converter for this property. /// public override TypeConverter Converter { get { // We only support public type converters, in order to avoid asserts. TypeConverter typeConverter = Property.Converter; if( typeConverter.GetType().IsPublic ) { return typeConverter; } else { return null; } } } ////// Gets a value indicating whether the member is browsable as specified in the /// BrowsableAttribute. /// public override bool IsBrowsable { get { return Property.IsBrowsable; } } ////// Gets a value indicating whether this property should be localized, as /// specified in the LocalizableAttribute. /// public override bool IsLocalizable { get { return Property.IsLocalizable; } } ////// Indicates whether value change notifications for this property may originate from outside the property /// descriptor, such as from the component itself (value=true), or whether notifications will only originate /// from direct calls made to PropertyDescriptor.SetValue (value=false). For example, the component may /// implement the INotifyPropertyChanged interface, or may have an explicit '{name}Changed' event for this property. /// public override bool SupportsChangeEvents { get { return Property.SupportsChangeEvents; } } #endregion Public Properties //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods ////// This method is called when we should clear our cached state. The cache /// may become invalid if someone adds additional type description providers. /// internal static void ClearCache() { lock (_cache) { _cache.Clear(); } } #endregion Internal Methods //----------------------------------------------------- // // Private Properties // //------------------------------------------------------ #region Private Properties // Return the property descriptor we're wrapping. We may have to get // this on demand if it wasn't passed into our constructor ////// Critical: calls TypeDescriptor.CreateProperty which LinkDemands /// TreatAsSafe: ok to create a property since we should have one anyway /// private PropertyDescriptor Property { [SecurityCritical, SecurityTreatAsSafe] get { if (_property == null) { _property = TypeDescriptor.GetProperties(_componentType)[Name]; if (_property == null) { // This should not normally happen. If it does, it means // that someone has messed around with metadata and has // removed this property from the type's metadata. We know // that there is really a CLR property, however, because // we are dealing with a direct property (only direct // properties can have their property descriptor delay // loaded). So, we can magically create one directly // from the CLR property through TypeDescriptor. _property = TypeDescriptor.CreateProperty(_componentType, Name, _dp.PropertyType); } } return _property; } } #endregion Private Properties //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- #region Private Fields private PropertyDescriptor _property; private Type _componentType; private DependencyProperty _dp; private bool _isAttached; private PropertyMetadata _metadata; // Synchronized by "_cache" private static Dictionary
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ToolStripTextBox.cs
- TimeSpanConverter.cs
- TableLayout.cs
- _NegotiateClient.cs
- HelpInfo.cs
- FileRegion.cs
- XPathLexer.cs
- XmlTextEncoder.cs
- FileSecurity.cs
- FragmentQuery.cs
- UnicastIPAddressInformationCollection.cs
- ConfigurationStrings.cs
- DesignOnlyAttribute.cs
- ApplyTemplatesAction.cs
- ResourceReferenceExpression.cs
- WorkflowEnvironment.cs
- HttpResponse.cs
- TabRenderer.cs
- OptimizerPatterns.cs
- BoolExpr.cs
- DebugView.cs
- WindowsSidIdentity.cs
- ScaleTransform3D.cs
- XmlSchemaExternal.cs
- XhtmlCssHandler.cs
- WsatProxy.cs
- SmiTypedGetterSetter.cs
- IItemContainerGenerator.cs
- Misc.cs
- indexingfiltermarshaler.cs
- XmlElementAttribute.cs
- FontResourceCache.cs
- UnderstoodHeaders.cs
- DefaultHttpHandler.cs
- SecurityDocument.cs
- ContextInformation.cs
- OrderedDictionary.cs
- HttpModuleActionCollection.cs
- WebFaultException.cs
- StringFormat.cs
- InternalBase.cs
- ApplicationFileCodeDomTreeGenerator.cs
- mediapermission.cs
- Viewport2DVisual3D.cs
- WebPartAuthorizationEventArgs.cs
- httpstaticobjectscollection.cs
- SynchronizationContext.cs
- DocumentCollection.cs
- TransactionProxy.cs
- UserInitiatedNavigationPermission.cs
- XhtmlCssHandler.cs
- PageHandlerFactory.cs
- EmptyReadOnlyDictionaryInternal.cs
- Gdiplus.cs
- ValueChangedEventManager.cs
- BinaryNode.cs
- TypeToTreeConverter.cs
- SponsorHelper.cs
- CachedPathData.cs
- RelationshipEndMember.cs
- SqlNotificationEventArgs.cs
- ContainsRowNumberChecker.cs
- Misc.cs
- MouseEvent.cs
- ReachSerializationCacheItems.cs
- DataTemplateKey.cs
- smtpconnection.cs
- DetailsView.cs
- CodeSubDirectoriesCollection.cs
- ResXDataNode.cs
- PolyLineSegment.cs
- WebSysDisplayNameAttribute.cs
- MenuCommand.cs
- MasterPageBuildProvider.cs
- PromptStyle.cs
- ExtendedPropertyInfo.cs
- TrackingServices.cs
- UIPropertyMetadata.cs
- Lazy.cs
- LightweightCodeGenerator.cs
- EntityViewGenerationAttribute.cs
- BamlLocalizationDictionary.cs
- ColorIndependentAnimationStorage.cs
- AdPostCacheSubstitution.cs
- securitycriticaldataformultiplegetandset.cs
- _Events.cs
- PropertyOverridesTypeEditor.cs
- OrderedDictionaryStateHelper.cs
- XmlImplementation.cs
- InputReportEventArgs.cs
- SafeTokenHandle.cs
- VectorCollectionValueSerializer.cs
- TypeBrowser.xaml.cs
- RequestBringIntoViewEventArgs.cs
- Mappings.cs
- LicenseProviderAttribute.cs
- SqlTriggerAttribute.cs
- AnonymousIdentificationSection.cs
- WindowShowOrOpenTracker.cs
- NativeMethods.cs