Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / 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; } } ////// This is the callback designers use to participate in the computation of property /// values at design time. Eg. Even if the author sets Visibility to Hidden, the designer /// wants to coerce the value to Visible at design time so that the element doesn't /// disappear from the design surface. /// public CoerceValueCallback DesignerCoerceValueCallback { get { return DependencyProperty.DesignerCoerceValueCallback; } set { DependencyProperty.DesignerCoerceValueCallback = value; } } #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
- DynamicILGenerator.cs
- TargetConverter.cs
- DataError.cs
- HttpListenerPrefixCollection.cs
- ToolStripComboBox.cs
- webbrowsersite.cs
- QilReplaceVisitor.cs
- MetabaseSettingsIis7.cs
- EventTrigger.cs
- DeclaredTypeElement.cs
- ListItemViewControl.cs
- DesignerRegionMouseEventArgs.cs
- RoleService.cs
- ToolboxItem.cs
- StackBuilderSink.cs
- Rotation3DAnimationUsingKeyFrames.cs
- TimerElapsedEvenArgs.cs
- ResourceReferenceKeyNotFoundException.cs
- ProxyWebPartManagerDesigner.cs
- RadioButton.cs
- Helpers.cs
- EtwProvider.cs
- RelationshipSet.cs
- UmAlQuraCalendar.cs
- InfoCardRSACryptoProvider.cs
- AdapterDictionary.cs
- HtmlShim.cs
- PieceDirectory.cs
- FontDialog.cs
- TextElementEditingBehaviorAttribute.cs
- SecurityUniqueId.cs
- HyperLinkColumn.cs
- JavaScriptObjectDeserializer.cs
- NamedPipeProcessProtocolHandler.cs
- __Error.cs
- Int64Animation.cs
- AssemblyInfo.cs
- DesignerCategoryAttribute.cs
- HttpServerVarsCollection.cs
- TagPrefixInfo.cs
- Transaction.cs
- XhtmlBasicCommandAdapter.cs
- FlowDocumentFormatter.cs
- BitmapEffectGroup.cs
- FixedSOMGroup.cs
- Header.cs
- TextEvent.cs
- PlanCompiler.cs
- keycontainerpermission.cs
- XsdDateTime.cs
- cookie.cs
- ColorMatrix.cs
- FormattedTextSymbols.cs
- ActivityWithResultConverter.cs
- XmlSortKey.cs
- SendMailErrorEventArgs.cs
- ClientEventManager.cs
- Marshal.cs
- WindowVisualStateTracker.cs
- IntSecurity.cs
- OperatingSystem.cs
- MachineKeySection.cs
- Encoder.cs
- FixedSOMLineRanges.cs
- KerberosSecurityTokenProvider.cs
- DataGridRowAutomationPeer.cs
- EntityTemplateFactory.cs
- TextBox.cs
- XamlVector3DCollectionSerializer.cs
- Line.cs
- ExistsInCollection.cs
- GridView.cs
- bidPrivateBase.cs
- FrameworkElementFactory.cs
- AuthenticationModuleElementCollection.cs
- ConnectionManagementElementCollection.cs
- TextTreeUndoUnit.cs
- SamlAuthenticationStatement.cs
- PersianCalendar.cs
- ResponseBodyWriter.cs
- CategoriesDocument.cs
- SplashScreenNativeMethods.cs
- ColorConverter.cs
- MaterialGroup.cs
- sqlpipe.cs
- DataGridViewRowCollection.cs
- RegistrationServices.cs
- Menu.cs
- coordinatorscratchpad.cs
- TextTreeUndo.cs
- VectorConverter.cs
- ProcessManager.cs
- CommandConverter.cs
- HttpEncoder.cs
- InplaceBitmapMetadataWriter.cs
- AttributedMetaModel.cs
- CollectionDataContract.cs
- PropertyEntry.cs
- AdRotator.cs
- CommandHelpers.cs