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
- TemplatedMailWebEventProvider.cs
- StreamProxy.cs
- DataGridViewBindingCompleteEventArgs.cs
- NativeMethods.cs
- SoundPlayer.cs
- CorrelationManager.cs
- WebConfigurationHost.cs
- SerializationInfo.cs
- Rijndael.cs
- xmlfixedPageInfo.cs
- HtmlHead.cs
- ETagAttribute.cs
- X509Chain.cs
- XmlValidatingReader.cs
- SystemUdpStatistics.cs
- RegisteredDisposeScript.cs
- InheritanceRules.cs
- DataTemplateKey.cs
- StreamGeometry.cs
- AsyncCodeActivityContext.cs
- XmlValueConverter.cs
- FastEncoderWindow.cs
- BrowserTree.cs
- SessionParameter.cs
- FilterableAttribute.cs
- Ref.cs
- PopupEventArgs.cs
- SyntaxCheck.cs
- infer.cs
- mda.cs
- ToolStripGrip.cs
- ConstraintEnumerator.cs
- CroppedBitmap.cs
- XomlCompilerError.cs
- GeneratedCodeAttribute.cs
- TypeUtil.cs
- ConstraintConverter.cs
- HostedElements.cs
- InProcStateClientManager.cs
- EntityDataSourceQueryBuilder.cs
- ComplexTypeEmitter.cs
- SqlFormatter.cs
- EmbeddedMailObject.cs
- SqlNamer.cs
- UInt32.cs
- SystemGatewayIPAddressInformation.cs
- NegatedCellConstant.cs
- ByteAnimationUsingKeyFrames.cs
- DataGridPagerStyle.cs
- XsltOutput.cs
- UnionQueryOperator.cs
- GestureRecognitionResult.cs
- CellConstantDomain.cs
- DecoderFallbackWithFailureFlag.cs
- ContentPathSegment.cs
- XmlDsigSep2000.cs
- SystemNetHelpers.cs
- RegistryKey.cs
- DockingAttribute.cs
- AccessControlEntry.cs
- EntityExpressionVisitor.cs
- SimpleRecyclingCache.cs
- RelatedImageListAttribute.cs
- CryptoSession.cs
- PixelFormats.cs
- UndoManager.cs
- XmlEnumAttribute.cs
- ListItemParagraph.cs
- ClrPerspective.cs
- StringUtil.cs
- XmlLoader.cs
- NumericUpDownAccelerationCollection.cs
- EventArgs.cs
- PointValueSerializer.cs
- Evidence.cs
- Variable.cs
- HtmlElement.cs
- OpCopier.cs
- Soap.cs
- DataPagerCommandEventArgs.cs
- TreeChangeInfo.cs
- sqlpipe.cs
- PageAsyncTask.cs
- ButtonColumn.cs
- ReadOnlyTernaryTree.cs
- CharAnimationBase.cs
- FontUnit.cs
- XPathSelfQuery.cs
- Oid.cs
- ToggleButtonAutomationPeer.cs
- Convert.cs
- ContourSegment.cs
- PrivilegedConfigurationManager.cs
- RecognizeCompletedEventArgs.cs
- PtsContext.cs
- SharedPerformanceCounter.cs
- LocatorGroup.cs
- MultipartContentParser.cs
- RawTextInputReport.cs
- DebugInfo.cs