Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / 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
- FtpWebRequest.cs
- DrawingBrush.cs
- BitmapImage.cs
- ObjectDataSourceSelectingEventArgs.cs
- mediaclock.cs
- SQLInt16Storage.cs
- Ipv6Element.cs
- EnumerableCollectionView.cs
- DataGridViewImageColumn.cs
- SyndicationSerializer.cs
- HtmlTable.cs
- AsyncOperation.cs
- ClientWindowsAuthenticationMembershipProvider.cs
- PenCursorManager.cs
- BinaryMethodMessage.cs
- AppSettingsExpressionBuilder.cs
- ReplacementText.cs
- ItemCollection.cs
- SpeechEvent.cs
- ListView.cs
- PointKeyFrameCollection.cs
- MulticastNotSupportedException.cs
- InputElement.cs
- OverflowException.cs
- FrugalMap.cs
- LineProperties.cs
- CheckBoxAutomationPeer.cs
- DebuggerService.cs
- RegionInfo.cs
- SkinBuilder.cs
- ImmutableDispatchRuntime.cs
- Unit.cs
- ValueOfAction.cs
- ConfigurationCollectionAttribute.cs
- TranslateTransform.cs
- DefaultWorkflowTransactionService.cs
- RuleSettingsCollection.cs
- InvalidPropValue.cs
- ExtensionQuery.cs
- UpdateTranslator.cs
- EditorAttribute.cs
- GeometryDrawing.cs
- AuthorizationRule.cs
- WebConfigManager.cs
- TextSimpleMarkerProperties.cs
- SoapAttributeOverrides.cs
- Propagator.Evaluator.cs
- CompiledRegexRunner.cs
- DBSqlParserColumn.cs
- DataRow.cs
- PeerResolverMode.cs
- BinaryQueryOperator.cs
- ContextStack.cs
- TextEditorSelection.cs
- TabItem.cs
- ConcurrentQueue.cs
- wgx_commands.cs
- ApplicationDirectory.cs
- AdCreatedEventArgs.cs
- MouseButtonEventArgs.cs
- TreeViewItem.cs
- ResourcePermissionBaseEntry.cs
- PrintPreviewDialog.cs
- XdrBuilder.cs
- HttpDictionary.cs
- PreProcessInputEventArgs.cs
- DesignerEditorPartChrome.cs
- ClientApiGenerator.cs
- CodeExpressionStatement.cs
- DataServices.cs
- PrimitiveXmlSerializers.cs
- CaretElement.cs
- FixedHyperLink.cs
- MethodExpr.cs
- ByteStorage.cs
- ConfigXmlWhitespace.cs
- AvtEvent.cs
- SoapInteropTypes.cs
- XmlStreamStore.cs
- validation.cs
- BindingExpression.cs
- StatusBarPanel.cs
- ClientConfigurationHost.cs
- RegexCompiler.cs
- CounterCreationData.cs
- RemotingServices.cs
- Separator.cs
- WinEventHandler.cs
- ErrorTableItemStyle.cs
- DbgCompiler.cs
- PageScaling.cs
- Gdiplus.cs
- EventProviderWriter.cs
- OutputCacheProfile.cs
- KoreanCalendar.cs
- WebPartChrome.cs
- SetterBaseCollection.cs
- RuntimeHelpers.cs
- CounterSample.cs
- ComponentChangingEvent.cs