Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Base / MS / Internal / ComponentModel / APCustomTypeDescriptor.cs / 1 / APCustomTypeDescriptor.cs
namespace 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;
///
/// This class is a custom type descriptor for attached dependency properties. We
/// could just inherit from the CustomTypeDescriptor class, which does most of the forwarding
/// work for us, but these are allocated a lot so we want them to be structs.
///
struct APCustomTypeDescriptor : ICustomTypeDescriptor {
//------------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
/// Creates a new APCustomTypeDescriptor. We pass in the custom type descriptor of
/// our base provider, which provides is with a default implementation of everything
/// we don't override. for us, we want to override only the property mechanism.
///
internal APCustomTypeDescriptor(ICustomTypeDescriptor parent, object instance)
{
_parent = parent;
_instance = FromObj(instance);
}
#endregion Constructors
//-----------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region Public Methods
///
/// Returns a collection of properties for our object. We first rely on base
/// CLR properties and then we attempt to match these with dependency properties.
///
public PropertyDescriptorCollection GetProperties()
{
return GetProperties(null);
}
///
/// Returns a collection of properties for our object. We first rely on base
/// CLR properties and then we attempt to match these with dependency properties.
///
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
// Because attached properties can come and go at any time,
// the set of properties we have here always needs to be rebuilt.
// We have two code paths here based on filtered attributes. An attribute
// filter is just a notificaiton of a filter, it doesn't actually perform
// the filter. Because the default PropertyFilterAttribute is PropertyFilter.All,
// it acts as a nice "don't care" in later filtering stages that TypeDescriptor
// may apply. That means that regardless of the filter value, we don't have
// to fiddle with adding the attribute to the property descriptor.
PropertyFilterOptions filter = PropertyFilterOptions.Valid | PropertyFilterOptions.SetValues;
if (attributes != null)
{
foreach (Attribute attr in attributes)
{
PropertyFilterAttribute filterAttr = attr as PropertyFilterAttribute;
if (filterAttr != null)
{
filter = filterAttr.Filter;
break;
}
}
}
if (filter == PropertyFilterOptions.None)
{
return PropertyDescriptorCollection.Empty;
}
// First, get the set of all known registered properties in the
// app domain. GetRegisteredProperties caches its results and
// will automatically re-fetch if new properties have been
// registered
DependencyProperty[] registeredProperties = GetRegisteredProperties();
Type instanceType = _instance.GetType();
// Next, walk through them and see which ones can be attached to this
// object. If our filter is specifically SetValues, we can
// greatly shortcut the entire process by using the local value
// enumerator.
List filteredProps;
if (filter == PropertyFilterOptions.SetValues)
{
LocalValueEnumerator localEnum = _instance.GetLocalValueEnumerator();
filteredProps = new List(localEnum.Count);
while(localEnum.MoveNext())
{
DependencyProperty dp = localEnum.Current.Property;
DependencyPropertyKind kind = DependencyObjectProvider.GetDependencyPropertyKind(dp, instanceType);
// For locally set values, we just want to exclude direct and internal properties.
if (!kind.IsDirect && !kind.IsInternal)
{
DependencyObjectPropertyDescriptor dpProp = DependencyObjectProvider.GetAttachedPropertyDescriptor(dp, instanceType);
filteredProps.Add(dpProp);
}
}
}
else
{
filteredProps = new List(registeredProperties.Length);
foreach (DependencyProperty dp in registeredProperties)
{
bool addProp = false;
DependencyPropertyKind kind = DependencyObjectProvider.GetDependencyPropertyKind(dp, instanceType);
if (kind.IsAttached)
{
// Check bit combinations that would yield true in
// any case. For non-attached properties, they're all valid, so if
// the valid bit is set, we're done.
PropertyFilterOptions anySet = PropertyFilterOptions.SetValues | PropertyFilterOptions.UnsetValues;
PropertyFilterOptions anyValid = PropertyFilterOptions.Valid | PropertyFilterOptions.Invalid;
if ((filter & anySet) == anySet || (filter & anyValid) == anyValid)
{
addProp = true;
}
if (!addProp && (filter & anyValid) != 0)
{
bool canAttach = CanAttachProperty(dp, _instance);
addProp = canAttach ^ ((filter & anyValid) == PropertyFilterOptions.Invalid);
}
if (!addProp && (filter & anySet) != 0)
{
bool shouldSerialize = _instance.ContainsValue(dp);
addProp = shouldSerialize ^ ((filter & anySet) == PropertyFilterOptions.UnsetValues);
}
}
else if ((filter & PropertyFilterOptions.SetValues) != 0 && _instance.ContainsValue(dp) && !kind.IsDirect && !kind.IsInternal)
{
// The property is not attached. However, it isn't an internal DP and the user
// has requested set values. See if the property is set on the object and include
// it if it is.
addProp = true;
}
if (addProp)
{
DependencyObjectPropertyDescriptor dpProp = DependencyObjectProvider.GetAttachedPropertyDescriptor(dp, instanceType);
filteredProps.Add(dpProp);
}
}
}
PropertyDescriptorCollection properties;
properties = new PropertyDescriptorCollection(filteredProps.ToArray(), true);
return properties;
}
//
// All methods below simply forward to the parent descriptor.
//
public AttributeCollection GetAttributes() { return _parent.GetAttributes(); }
public string GetClassName() { return _parent.GetClassName(); }
public string GetComponentName() { return _parent.GetComponentName(); }
public TypeConverter GetConverter()
{
// We only support public type converters, in order to avoid asserts.
TypeConverter typeConverter = _parent.GetConverter();
if( typeConverter.GetType().IsPublic )
{
return typeConverter;
}
else
{
return null;
}
}
public EventDescriptor GetDefaultEvent() { return _parent.GetDefaultEvent(); }
public PropertyDescriptor GetDefaultProperty() { return _parent.GetDefaultProperty(); }
public object GetEditor(Type editorBaseType) { return _parent.GetEditor(editorBaseType); }
public EventDescriptorCollection GetEvents() { return _parent.GetEvents(); }
public EventDescriptorCollection GetEvents(Attribute[] attributes) { return _parent.GetEvents(attributes); }
public object GetPropertyOwner(PropertyDescriptor property) { return _parent.GetPropertyOwner(property); }
#endregion Public Methods
//------------------------------------------------------
//
// Private Methods
//
//-----------------------------------------------------
#region Private Methods
///
/// This method determines if the given property can be attached
/// to the given instance.
///
private bool CanAttachProperty(DependencyProperty dp, DependencyObject instance)
{
AttachInfo info = DependencyObjectProvider.GetAttachInfo(dp);
return info.CanAttach(instance);
}
///
/// Returns a dependency object for the given value.
///
private static DependencyObject FromObj(object value)
{
// This indirection is necessary to support
// the "association" feature of type descriptor. This feature
// alows one object to mimic the API of another.
return (DependencyObject)TypeDescriptor.GetAssociation(typeof(DependencyObject), value);
}
///
/// Returns an array of all registered properties declared in the
/// system.
///
private DependencyProperty[] GetRegisteredProperties()
{
DependencyProperty[] registeredProperties;
// We keep track of the global dependency property count.
// Because DPs are never removed, we use this value to
// verify if our cache of registered properties is up to date.
// If the count doesn't match our cached count, we re-fetch
// all registered properties.
lock(_syncLock)
{
int cacheCnt = _dpCacheCount;
int currentCnt = DependencyProperty.RegisteredPropertyCount;
if (_dpCacheArray == null || cacheCnt != currentCnt)
{
List dpList = new List(currentCnt);
lock(DependencyProperty.Synchronized)
{
foreach(DependencyProperty dp in DependencyProperty.RegisteredProperties)
{
dpList.Add(dp);
}
_dpCacheCount = DependencyProperty.RegisteredPropertyCount;
_dpCacheArray = dpList.ToArray();
}
}
registeredProperties = _dpCacheArray;
}
return registeredProperties;
}
#endregion Private Methods
//------------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
private ICustomTypeDescriptor _parent;
private DependencyObject _instance;
private static object _syncLock = new object();
// Synchronized by "_syncLock"
private static int _dpCacheCount = 0;
// Synchronized by "_syncLock"
private static DependencyProperty[] _dpCacheArray;
#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 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;
///
/// This class is a custom type descriptor for attached dependency properties. We
/// could just inherit from the CustomTypeDescriptor class, which does most of the forwarding
/// work for us, but these are allocated a lot so we want them to be structs.
///
struct APCustomTypeDescriptor : ICustomTypeDescriptor {
//------------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
/// Creates a new APCustomTypeDescriptor. We pass in the custom type descriptor of
/// our base provider, which provides is with a default implementation of everything
/// we don't override. for us, we want to override only the property mechanism.
///
internal APCustomTypeDescriptor(ICustomTypeDescriptor parent, object instance)
{
_parent = parent;
_instance = FromObj(instance);
}
#endregion Constructors
//-----------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region Public Methods
///
/// Returns a collection of properties for our object. We first rely on base
/// CLR properties and then we attempt to match these with dependency properties.
///
public PropertyDescriptorCollection GetProperties()
{
return GetProperties(null);
}
///
/// Returns a collection of properties for our object. We first rely on base
/// CLR properties and then we attempt to match these with dependency properties.
///
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
// Because attached properties can come and go at any time,
// the set of properties we have here always needs to be rebuilt.
// We have two code paths here based on filtered attributes. An attribute
// filter is just a notificaiton of a filter, it doesn't actually perform
// the filter. Because the default PropertyFilterAttribute is PropertyFilter.All,
// it acts as a nice "don't care" in later filtering stages that TypeDescriptor
// may apply. That means that regardless of the filter value, we don't have
// to fiddle with adding the attribute to the property descriptor.
PropertyFilterOptions filter = PropertyFilterOptions.Valid | PropertyFilterOptions.SetValues;
if (attributes != null)
{
foreach (Attribute attr in attributes)
{
PropertyFilterAttribute filterAttr = attr as PropertyFilterAttribute;
if (filterAttr != null)
{
filter = filterAttr.Filter;
break;
}
}
}
if (filter == PropertyFilterOptions.None)
{
return PropertyDescriptorCollection.Empty;
}
// First, get the set of all known registered properties in the
// app domain. GetRegisteredProperties caches its results and
// will automatically re-fetch if new properties have been
// registered
DependencyProperty[] registeredProperties = GetRegisteredProperties();
Type instanceType = _instance.GetType();
// Next, walk through them and see which ones can be attached to this
// object. If our filter is specifically SetValues, we can
// greatly shortcut the entire process by using the local value
// enumerator.
List filteredProps;
if (filter == PropertyFilterOptions.SetValues)
{
LocalValueEnumerator localEnum = _instance.GetLocalValueEnumerator();
filteredProps = new List(localEnum.Count);
while(localEnum.MoveNext())
{
DependencyProperty dp = localEnum.Current.Property;
DependencyPropertyKind kind = DependencyObjectProvider.GetDependencyPropertyKind(dp, instanceType);
// For locally set values, we just want to exclude direct and internal properties.
if (!kind.IsDirect && !kind.IsInternal)
{
DependencyObjectPropertyDescriptor dpProp = DependencyObjectProvider.GetAttachedPropertyDescriptor(dp, instanceType);
filteredProps.Add(dpProp);
}
}
}
else
{
filteredProps = new List(registeredProperties.Length);
foreach (DependencyProperty dp in registeredProperties)
{
bool addProp = false;
DependencyPropertyKind kind = DependencyObjectProvider.GetDependencyPropertyKind(dp, instanceType);
if (kind.IsAttached)
{
// Check bit combinations that would yield true in
// any case. For non-attached properties, they're all valid, so if
// the valid bit is set, we're done.
PropertyFilterOptions anySet = PropertyFilterOptions.SetValues | PropertyFilterOptions.UnsetValues;
PropertyFilterOptions anyValid = PropertyFilterOptions.Valid | PropertyFilterOptions.Invalid;
if ((filter & anySet) == anySet || (filter & anyValid) == anyValid)
{
addProp = true;
}
if (!addProp && (filter & anyValid) != 0)
{
bool canAttach = CanAttachProperty(dp, _instance);
addProp = canAttach ^ ((filter & anyValid) == PropertyFilterOptions.Invalid);
}
if (!addProp && (filter & anySet) != 0)
{
bool shouldSerialize = _instance.ContainsValue(dp);
addProp = shouldSerialize ^ ((filter & anySet) == PropertyFilterOptions.UnsetValues);
}
}
else if ((filter & PropertyFilterOptions.SetValues) != 0 && _instance.ContainsValue(dp) && !kind.IsDirect && !kind.IsInternal)
{
// The property is not attached. However, it isn't an internal DP and the user
// has requested set values. See if the property is set on the object and include
// it if it is.
addProp = true;
}
if (addProp)
{
DependencyObjectPropertyDescriptor dpProp = DependencyObjectProvider.GetAttachedPropertyDescriptor(dp, instanceType);
filteredProps.Add(dpProp);
}
}
}
PropertyDescriptorCollection properties;
properties = new PropertyDescriptorCollection(filteredProps.ToArray(), true);
return properties;
}
//
// All methods below simply forward to the parent descriptor.
//
public AttributeCollection GetAttributes() { return _parent.GetAttributes(); }
public string GetClassName() { return _parent.GetClassName(); }
public string GetComponentName() { return _parent.GetComponentName(); }
public TypeConverter GetConverter()
{
// We only support public type converters, in order to avoid asserts.
TypeConverter typeConverter = _parent.GetConverter();
if( typeConverter.GetType().IsPublic )
{
return typeConverter;
}
else
{
return null;
}
}
public EventDescriptor GetDefaultEvent() { return _parent.GetDefaultEvent(); }
public PropertyDescriptor GetDefaultProperty() { return _parent.GetDefaultProperty(); }
public object GetEditor(Type editorBaseType) { return _parent.GetEditor(editorBaseType); }
public EventDescriptorCollection GetEvents() { return _parent.GetEvents(); }
public EventDescriptorCollection GetEvents(Attribute[] attributes) { return _parent.GetEvents(attributes); }
public object GetPropertyOwner(PropertyDescriptor property) { return _parent.GetPropertyOwner(property); }
#endregion Public Methods
//------------------------------------------------------
//
// Private Methods
//
//-----------------------------------------------------
#region Private Methods
///
/// This method determines if the given property can be attached
/// to the given instance.
///
private bool CanAttachProperty(DependencyProperty dp, DependencyObject instance)
{
AttachInfo info = DependencyObjectProvider.GetAttachInfo(dp);
return info.CanAttach(instance);
}
///
/// Returns a dependency object for the given value.
///
private static DependencyObject FromObj(object value)
{
// This indirection is necessary to support
// the "association" feature of type descriptor. This feature
// alows one object to mimic the API of another.
return (DependencyObject)TypeDescriptor.GetAssociation(typeof(DependencyObject), value);
}
///
/// Returns an array of all registered properties declared in the
/// system.
///
private DependencyProperty[] GetRegisteredProperties()
{
DependencyProperty[] registeredProperties;
// We keep track of the global dependency property count.
// Because DPs are never removed, we use this value to
// verify if our cache of registered properties is up to date.
// If the count doesn't match our cached count, we re-fetch
// all registered properties.
lock(_syncLock)
{
int cacheCnt = _dpCacheCount;
int currentCnt = DependencyProperty.RegisteredPropertyCount;
if (_dpCacheArray == null || cacheCnt != currentCnt)
{
List dpList = new List(currentCnt);
lock(DependencyProperty.Synchronized)
{
foreach(DependencyProperty dp in DependencyProperty.RegisteredProperties)
{
dpList.Add(dp);
}
_dpCacheCount = DependencyProperty.RegisteredPropertyCount;
_dpCacheArray = dpList.ToArray();
}
}
registeredProperties = _dpCacheArray;
}
return registeredProperties;
}
#endregion Private Methods
//------------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
private ICustomTypeDescriptor _parent;
private DependencyObject _instance;
private static object _syncLock = new object();
// Synchronized by "_syncLock"
private static int _dpCacheCount = 0;
// Synchronized by "_syncLock"
private static DependencyProperty[] _dpCacheArray;
#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
- OperationInvokerBehavior.cs
- HtmlInputPassword.cs
- SHA512Managed.cs
- LogLogRecordHeader.cs
- TouchEventArgs.cs
- NonBatchDirectoryCompiler.cs
- TextStore.cs
- ProcessHostServerConfig.cs
- ReadOnlyPropertyMetadata.cs
- AccessText.cs
- SystemColorTracker.cs
- XPathSelectionIterator.cs
- SystemColors.cs
- UnaryNode.cs
- ObjectDataSourceStatusEventArgs.cs
- XamlToRtfParser.cs
- PhysicalFontFamily.cs
- StylusButtonEventArgs.cs
- LineProperties.cs
- EntityParameter.cs
- AddInToken.cs
- DispatcherTimer.cs
- NativeCppClassAttribute.cs
- ResourceReferenceExpressionConverter.cs
- SqlDataSourceSummaryPanel.cs
- BindingWorker.cs
- Convert.cs
- TriggerAction.cs
- CompModSwitches.cs
- ListBase.cs
- Vector3D.cs
- SafeBitVector32.cs
- StorageScalarPropertyMapping.cs
- SchemaLookupTable.cs
- SqlServer2KCompatibilityAnnotation.cs
- FormatConvertedBitmap.cs
- FloaterParaClient.cs
- ArgumentValue.cs
- Win32.cs
- HitTestResult.cs
- BindingExpressionBase.cs
- MultiBinding.cs
- SpellCheck.cs
- StrongNameUtility.cs
- BindMarkupExtensionSerializer.cs
- XsdDuration.cs
- XmlEncodedRawTextWriter.cs
- ImageClickEventArgs.cs
- DataTableClearEvent.cs
- XmlAnyElementAttributes.cs
- _LocalDataStore.cs
- EventLogSession.cs
- _FtpDataStream.cs
- FixedSchema.cs
- RadioButtonPopupAdapter.cs
- FrameworkContentElement.cs
- SqlConnectionPoolGroupProviderInfo.cs
- PageRanges.cs
- XmlNode.cs
- TypeResolver.cs
- DataSvcMapFile.cs
- httpapplicationstate.cs
- Internal.cs
- Int32.cs
- FontDialog.cs
- Menu.cs
- SystemIPGlobalStatistics.cs
- XmlReturnReader.cs
- WebPartVerb.cs
- MarkupExtensionReturnTypeAttribute.cs
- WindowsGrip.cs
- HttpBindingExtension.cs
- CheckBox.cs
- PropertyMap.cs
- Registry.cs
- DelimitedListTraceListener.cs
- Control.cs
- CmsInterop.cs
- HttpRuntimeSection.cs
- ChameleonKey.cs
- SqlXml.cs
- MatrixAnimationBase.cs
- XmlSchemaComplexType.cs
- IdnMapping.cs
- XmlStrings.cs
- CommentEmitter.cs
- GeneralTransform3DGroup.cs
- XdrBuilder.cs
- GradientBrush.cs
- MenuItemCollection.cs
- DbCommandDefinition.cs
- ListControl.cs
- CodeCatchClauseCollection.cs
- InternalsVisibleToAttribute.cs
- ModelService.cs
- HwndHost.cs
- CodeLabeledStatement.cs
- ExpressionBuilderCollection.cs
- ServiceDescriptionContext.cs
- OperatingSystem.cs