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
- DataControlFieldCollection.cs
- MetabaseServerConfig.cs
- RegexGroupCollection.cs
- ParserExtension.cs
- HttpCookiesSection.cs
- ByteStreamBufferedMessageData.cs
- SimpleApplicationHost.cs
- TargetInvocationException.cs
- XsltArgumentList.cs
- XmlWriterSettings.cs
- CollectionExtensions.cs
- WebPartVerbCollection.cs
- WindowsFormsHelpers.cs
- CoTaskMemHandle.cs
- HWStack.cs
- EditorPart.cs
- MarshalByRefObject.cs
- SizeFConverter.cs
- RewritingSimplifier.cs
- TreeViewCancelEvent.cs
- XslException.cs
- _Rfc2616CacheValidators.cs
- SafeSecurityHelper.cs
- IgnoreFileBuildProvider.cs
- RenamedEventArgs.cs
- XmlSchemaDocumentation.cs
- NetworkInformationException.cs
- MessageBox.cs
- TextTreeTextElementNode.cs
- ApplicationServiceHelper.cs
- StringKeyFrameCollection.cs
- UndoManager.cs
- BigIntegerStorage.cs
- TypeUsage.cs
- Timer.cs
- PrintDialog.cs
- DynamicPropertyReader.cs
- NameSpaceExtractor.cs
- DataBindingValueUIHandler.cs
- DiscoveryDocumentLinksPattern.cs
- OutputWindow.cs
- EditorPartDesigner.cs
- RegexMatch.cs
- AttributeQuery.cs
- PartialArray.cs
- PageEventArgs.cs
- WeakEventTable.cs
- WindowManager.cs
- QueryGenerator.cs
- LifetimeManager.cs
- filewebresponse.cs
- EventItfInfo.cs
- SurrogateDataContract.cs
- Condition.cs
- VisualTarget.cs
- ServiceChannelManager.cs
- StateRuntime.cs
- DataGridViewImageCell.cs
- PersonalizationProviderCollection.cs
- Debug.cs
- BindingEntityInfo.cs
- JapaneseCalendar.cs
- EntityDataSourceDataSelectionPanel.cs
- SqlParameterizer.cs
- Brush.cs
- Size.cs
- XslException.cs
- SkewTransform.cs
- DesignerForm.cs
- ClipboardData.cs
- TableRowsCollectionEditor.cs
- DataGridViewCellPaintingEventArgs.cs
- User.cs
- CRYPTPROTECT_PROMPTSTRUCT.cs
- TCEAdapterGenerator.cs
- DrawingImage.cs
- AppDomainFactory.cs
- ISCIIEncoding.cs
- EditingMode.cs
- SchemaMapping.cs
- ActivityScheduledQuery.cs
- MetadataArtifactLoaderResource.cs
- FunctionNode.cs
- PointLightBase.cs
- arabicshape.cs
- DBSchemaTable.cs
- __Filters.cs
- CompilerWrapper.cs
- HttpAsyncResult.cs
- MethodBuilder.cs
- RtfControlWordInfo.cs
- CodeCompileUnit.cs
- HashAlgorithm.cs
- mongolianshape.cs
- Invariant.cs
- NativeMethods.cs
- TextProperties.cs
- DrawListViewColumnHeaderEventArgs.cs
- PasswordBox.cs
- ResXResourceReader.cs