Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Base / MS / Internal / ComponentModel / DependencyObjectProvider.cs / 1 / DependencyObjectProvider.cs
namespace MS.Internal.ComponentModel
{
using MS.Internal.ComponentModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Windows;
using System.Windows.Markup;
using System.Text;
///
/// A type description provider provides metadata for types. It allows a type
/// to define its own semantic layer for properties, events and attributes.
///
/// Note: This class can stay internal. To utilize it, the following
/// metadata attribute should be added to DependencyObject:
///
/// [TypeDescriptionProvider(typeof(DependencyObjectProvider))]
/// public class DependencyObject {}
///
internal sealed class DependencyObjectProvider : TypeDescriptionProvider {
//------------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
/// The ctor for this class needs to be public because it is created
/// by TypeDescriptor using reflection.
///
public DependencyObjectProvider() : base(TypeDescriptor.GetProvider(typeof(DependencyObject)))
{
// We keep a lot of caches around. When TypeDescriptor gets a refresh
// we clear our caches. We only need to do this if the refresh
// contains type information, because we only keep static per-type
// caches.
TypeDescriptor.Refreshed += delegate(RefreshEventArgs args)
{
if (args.TypeChanged != null && typeof(DependencyObject).IsAssignableFrom(args.TypeChanged))
{
ClearCache();
DependencyObjectPropertyDescriptor.ClearCache();
DPCustomTypeDescriptor.ClearCache();
DependencyPropertyDescriptor.ClearCache();
}
};
}
#endregion Constructors
//-----------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region Public Methods
///
/// Returns a custom type descriptor suitable for querying about the
/// given object type and instance.
///
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new DPCustomTypeDescriptor(base.GetTypeDescriptor(objectType, instance),
objectType, instance);
}
///
/// Returns a custom type descriptor suitable for querying about "extended"
/// properties. Extended properties are are attached properties in our world.
///
public override ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance)
{
ICustomTypeDescriptor descriptor = base.GetExtendedTypeDescriptor(instance);
// It is possible that a Type object worked its way in here as an instance.
// If it did, we don't need our own descriptor because we don't support
// attached properties on type instances.
if (instance != null && !(instance is Type))
{
descriptor = new APCustomTypeDescriptor(descriptor, instance);
}
return descriptor;
}
///
/// Returns a caching layer type descriptor will use to store
/// computed metadata.
///
public override IDictionary GetCache(object instance)
{
DependencyObject d = instance as DependencyObject;
// This should never happen because we are bound only
// to dependency object types. However, in case it
// does, simply invoke the base and get out.
if (d == null)
{
return base.GetCache(instance);
}
// The cache we return is used by TypeDescriptor to
// store cached metadata information. We demand create
// it here.
// If the DependencyObject is Sealed we cannot store
// the cache on it - if no cache exists already we
// will return null.
IDictionary cache = _cacheSlot.GetValue(d);
if (cache == null && !d.IsSealed)
{
cache = new Hashtable();
_cacheSlot.SetValue(d, cache);
}
return cache;
}
#endregion Public Methods
//------------------------------------------------------
//
// Public Properties
//
//-----------------------------------------------------
//------------------------------------------------------
//
// Public Events
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
///
/// This method is called when we should clear our cached state. The cache
/// may become invalid if someone adds additional type description providers.
///
private static void ClearCache()
{
lock (_propertyMap)
{
_propertyMap.Clear();
}
lock(_propertyKindMap)
{
_propertyKindMap.Clear();
}
lock(_attachInfoMap)
{
_attachInfoMap.Clear();
}
}
///
/// This method calculates the attach rules defined on
/// this dependency property. It always returns a valid
/// AttachInfo, but the fields in AttachInfo may be null.
///
internal static AttachInfo GetAttachInfo(DependencyProperty dp)
{
// Have we already seen this DP?
AttachInfo info = (AttachInfo)_attachInfoMap[dp];
if (info == null)
{
info = new AttachInfo(dp);
lock(_attachInfoMap)
{
_attachInfoMap[dp] = info;
}
}
return info;
}
#endregion Private Methods
//-----------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
#region Internal Methods
///
/// This method returns an attached property descriptor for the given DP and target type.
///
internal static DependencyObjectPropertyDescriptor GetAttachedPropertyDescriptor(DependencyProperty dp, Type targetType)
{
DependencyObjectPropertyDescriptor dpProp;
PropertyKey key = new PropertyKey(targetType, dp);
lock(_propertyMap)
{
if (!_propertyMap.TryGetValue(key, out dpProp))
{
dpProp = new DependencyObjectPropertyDescriptor(dp, targetType);
_propertyMap[key] = dpProp;
}
}
return dpProp;
}
///
/// This method returns a DependencyPropertyKind object which can
/// be used to tell if a given DP / target type combination represents
/// an attached or direct property.
///
internal static DependencyPropertyKind GetDependencyPropertyKind(DependencyProperty dp, Type targetType)
{
DependencyPropertyKind kind;
PropertyKey key = new PropertyKey(targetType, dp);
lock(_propertyKindMap)
{
if (!_propertyKindMap.TryGetValue(key, out kind))
{
kind = new DependencyPropertyKind(dp, targetType);
_propertyKindMap[key] = kind;
}
}
return kind;
}
#endregion Internal Methods
//-----------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
private static readonly UncommonField _cacheSlot = new UncommonField(null);
// Synchronized by "_propertyMap"
private static Dictionary _propertyMap = new Dictionary();
// Synchronized by "_propertyKindMap"
private static Dictionary _propertyKindMap = new Dictionary();
// Synchronized by "_attachInfoMap"
private static Hashtable _attachInfoMap = new Hashtable();
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace MS.Internal.ComponentModel
{
using MS.Internal.ComponentModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Windows;
using System.Windows.Markup;
using System.Text;
///
/// A type description provider provides metadata for types. It allows a type
/// to define its own semantic layer for properties, events and attributes.
///
/// Note: This class can stay internal. To utilize it, the following
/// metadata attribute should be added to DependencyObject:
///
/// [TypeDescriptionProvider(typeof(DependencyObjectProvider))]
/// public class DependencyObject {}
///
internal sealed class DependencyObjectProvider : TypeDescriptionProvider {
//------------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
/// The ctor for this class needs to be public because it is created
/// by TypeDescriptor using reflection.
///
public DependencyObjectProvider() : base(TypeDescriptor.GetProvider(typeof(DependencyObject)))
{
// We keep a lot of caches around. When TypeDescriptor gets a refresh
// we clear our caches. We only need to do this if the refresh
// contains type information, because we only keep static per-type
// caches.
TypeDescriptor.Refreshed += delegate(RefreshEventArgs args)
{
if (args.TypeChanged != null && typeof(DependencyObject).IsAssignableFrom(args.TypeChanged))
{
ClearCache();
DependencyObjectPropertyDescriptor.ClearCache();
DPCustomTypeDescriptor.ClearCache();
DependencyPropertyDescriptor.ClearCache();
}
};
}
#endregion Constructors
//-----------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region Public Methods
///
/// Returns a custom type descriptor suitable for querying about the
/// given object type and instance.
///
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new DPCustomTypeDescriptor(base.GetTypeDescriptor(objectType, instance),
objectType, instance);
}
///
/// Returns a custom type descriptor suitable for querying about "extended"
/// properties. Extended properties are are attached properties in our world.
///
public override ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance)
{
ICustomTypeDescriptor descriptor = base.GetExtendedTypeDescriptor(instance);
// It is possible that a Type object worked its way in here as an instance.
// If it did, we don't need our own descriptor because we don't support
// attached properties on type instances.
if (instance != null && !(instance is Type))
{
descriptor = new APCustomTypeDescriptor(descriptor, instance);
}
return descriptor;
}
///
/// Returns a caching layer type descriptor will use to store
/// computed metadata.
///
public override IDictionary GetCache(object instance)
{
DependencyObject d = instance as DependencyObject;
// This should never happen because we are bound only
// to dependency object types. However, in case it
// does, simply invoke the base and get out.
if (d == null)
{
return base.GetCache(instance);
}
// The cache we return is used by TypeDescriptor to
// store cached metadata information. We demand create
// it here.
// If the DependencyObject is Sealed we cannot store
// the cache on it - if no cache exists already we
// will return null.
IDictionary cache = _cacheSlot.GetValue(d);
if (cache == null && !d.IsSealed)
{
cache = new Hashtable();
_cacheSlot.SetValue(d, cache);
}
return cache;
}
#endregion Public Methods
//------------------------------------------------------
//
// Public Properties
//
//-----------------------------------------------------
//------------------------------------------------------
//
// Public Events
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
///
/// This method is called when we should clear our cached state. The cache
/// may become invalid if someone adds additional type description providers.
///
private static void ClearCache()
{
lock (_propertyMap)
{
_propertyMap.Clear();
}
lock(_propertyKindMap)
{
_propertyKindMap.Clear();
}
lock(_attachInfoMap)
{
_attachInfoMap.Clear();
}
}
///
/// This method calculates the attach rules defined on
/// this dependency property. It always returns a valid
/// AttachInfo, but the fields in AttachInfo may be null.
///
internal static AttachInfo GetAttachInfo(DependencyProperty dp)
{
// Have we already seen this DP?
AttachInfo info = (AttachInfo)_attachInfoMap[dp];
if (info == null)
{
info = new AttachInfo(dp);
lock(_attachInfoMap)
{
_attachInfoMap[dp] = info;
}
}
return info;
}
#endregion Private Methods
//-----------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
#region Internal Methods
///
/// This method returns an attached property descriptor for the given DP and target type.
///
internal static DependencyObjectPropertyDescriptor GetAttachedPropertyDescriptor(DependencyProperty dp, Type targetType)
{
DependencyObjectPropertyDescriptor dpProp;
PropertyKey key = new PropertyKey(targetType, dp);
lock(_propertyMap)
{
if (!_propertyMap.TryGetValue(key, out dpProp))
{
dpProp = new DependencyObjectPropertyDescriptor(dp, targetType);
_propertyMap[key] = dpProp;
}
}
return dpProp;
}
///
/// This method returns a DependencyPropertyKind object which can
/// be used to tell if a given DP / target type combination represents
/// an attached or direct property.
///
internal static DependencyPropertyKind GetDependencyPropertyKind(DependencyProperty dp, Type targetType)
{
DependencyPropertyKind kind;
PropertyKey key = new PropertyKey(targetType, dp);
lock(_propertyKindMap)
{
if (!_propertyKindMap.TryGetValue(key, out kind))
{
kind = new DependencyPropertyKind(dp, targetType);
_propertyKindMap[key] = kind;
}
}
return kind;
}
#endregion Internal Methods
//-----------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
private static readonly UncommonField _cacheSlot = new UncommonField(null);
// Synchronized by "_propertyMap"
private static Dictionary _propertyMap = new Dictionary();
// Synchronized by "_propertyKindMap"
private static Dictionary _propertyKindMap = new Dictionary();
// Synchronized by "_attachInfoMap"
private static Hashtable _attachInfoMap = new Hashtable();
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SystemIPInterfaceProperties.cs
- FontCacheUtil.cs
- DoWorkEventArgs.cs
- EncryptedData.cs
- AsymmetricSignatureDeformatter.cs
- Error.cs
- TextServicesCompartment.cs
- ScriptReferenceBase.cs
- InternalCache.cs
- WebPart.cs
- HttpRuntimeSection.cs
- LogoValidationException.cs
- GlobalProxySelection.cs
- IndexedEnumerable.cs
- DocumentReferenceCollection.cs
- MappingMetadataHelper.cs
- EventHandlerList.cs
- InfoCardRSAOAEPKeyExchangeFormatter.cs
- EncoderNLS.cs
- MessageSmuggler.cs
- XmlSchemaSimpleContentExtension.cs
- Resources.Designer.cs
- ProfileService.cs
- CellConstant.cs
- RouteParametersHelper.cs
- MultiView.cs
- NameValuePermission.cs
- FontStyle.cs
- DefaultProxySection.cs
- DataGridViewButtonCell.cs
- AddInServer.cs
- SqlFileStream.cs
- UnaryNode.cs
- ObjectFullSpanRewriter.cs
- Point4D.cs
- COM2TypeInfoProcessor.cs
- DoubleLinkListEnumerator.cs
- ListControl.cs
- FixedLineResult.cs
- DataSet.cs
- TableLayoutCellPaintEventArgs.cs
- InternalSafeNativeMethods.cs
- CurrencyWrapper.cs
- SqlRecordBuffer.cs
- EpmTargetPathSegment.cs
- CompileLiteralTextParser.cs
- TypedReference.cs
- SimpleRecyclingCache.cs
- InlineObject.cs
- EntityTransaction.cs
- DataGridViewComboBoxEditingControl.cs
- ArgumentDesigner.xaml.cs
- DefaultValidator.cs
- DataGridHeaderBorder.cs
- MouseActionConverter.cs
- ImmComposition.cs
- ListQueryResults.cs
- CodeDirectionExpression.cs
- DataSourceView.cs
- UnmanagedMarshal.cs
- CompilerCollection.cs
- AddInAdapter.cs
- DiscoveryOperationContextExtension.cs
- SoapSchemaImporter.cs
- BooleanFacetDescriptionElement.cs
- ClusterSafeNativeMethods.cs
- WindowManager.cs
- StoreAnnotationsMap.cs
- X509CertificateChain.cs
- ProviderSettings.cs
- MailMessage.cs
- SlipBehavior.cs
- ResizeGrip.cs
- mediapermission.cs
- ObservableDictionary.cs
- ObfuscateAssemblyAttribute.cs
- TransformerConfigurationWizardBase.cs
- SoundPlayer.cs
- DragEventArgs.cs
- Properties.cs
- TopClause.cs
- ListBindingHelper.cs
- WindowsBrush.cs
- XmlArrayAttribute.cs
- CodeNamespaceImport.cs
- KeyedHashAlgorithm.cs
- TraceSection.cs
- EntryPointNotFoundException.cs
- GenerateHelper.cs
- XmlWriterSettings.cs
- SqlNodeAnnotation.cs
- SafeWaitHandle.cs
- ExtensionQuery.cs
- ToolStripProfessionalLowResolutionRenderer.cs
- ContainerActivationHelper.cs
- RequestCachePolicyConverter.cs
- StyleTypedPropertyAttribute.cs
- ConfigurationFileMap.cs
- ApplicationFileCodeDomTreeGenerator.cs
- File.cs