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. ListfilteredProps; 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) { ListdpList = 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. ListfilteredProps; 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) { ListdpList = 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
- NativeMethods.cs
- EntityDataSourceContextCreatedEventArgs.cs
- DependencyObject.cs
- IdentitySection.cs
- SecurityTokenSerializer.cs
- BindingManagerDataErrorEventArgs.cs
- WinEventTracker.cs
- RenderOptions.cs
- XPathEmptyIterator.cs
- StringInfo.cs
- TextFormatterHost.cs
- TraceContextEventArgs.cs
- CircleHotSpot.cs
- XmlSchemaAnyAttribute.cs
- ExtractorMetadata.cs
- CodeExporter.cs
- SchemaImporterExtensionElement.cs
- RuntimeHandles.cs
- SchemaElementLookUpTableEnumerator.cs
- ISCIIEncoding.cs
- DataGridViewUtilities.cs
- Knowncolors.cs
- PrintPageEvent.cs
- FastEncoder.cs
- SafeNativeMethods.cs
- ForeignKeyFactory.cs
- HashCodeCombiner.cs
- ConstructorArgumentAttribute.cs
- PointAnimationUsingPath.cs
- BindUriHelper.cs
- CompilerGlobalScopeAttribute.cs
- SqlTransaction.cs
- StringHandle.cs
- glyphs.cs
- Rules.cs
- AssemblyAttributes.cs
- DrawingCollection.cs
- QueryResult.cs
- wpf-etw.cs
- BinaryUtilClasses.cs
- DeviceContext.cs
- CodeCommentStatementCollection.cs
- securitymgrsite.cs
- StorageEntityTypeMapping.cs
- UnmanagedMemoryStreamWrapper.cs
- TextBoxBase.cs
- ComEventsSink.cs
- SingleObjectCollection.cs
- SqlRemoveConstantOrderBy.cs
- ToolboxItem.cs
- wgx_render.cs
- HttpRuntimeSection.cs
- GlyphRun.cs
- BamlLocalizer.cs
- RequestCachePolicy.cs
- AnnotationMap.cs
- SoapUnknownHeader.cs
- SafeRightsManagementSessionHandle.cs
- Psha1DerivedKeyGenerator.cs
- Menu.cs
- ComponentManagerBroker.cs
- Errors.cs
- WebBrowserUriTypeConverter.cs
- UpdateRecord.cs
- WindowsImpersonationContext.cs
- ObjectStorage.cs
- MobileControlsSection.cs
- FixedSOMFixedBlock.cs
- PropertyIDSet.cs
- DefinitionBase.cs
- PathFigure.cs
- WasNotInstalledException.cs
- ResourceDictionary.cs
- StrongTypingException.cs
- SqlUserDefinedTypeAttribute.cs
- QueryComponents.cs
- MeshGeometry3D.cs
- XmlConvert.cs
- BindStream.cs
- IDReferencePropertyAttribute.cs
- ClassValidator.cs
- StreamHelper.cs
- GroupByExpressionRewriter.cs
- PropertyChangedEventArgs.cs
- BrowserTree.cs
- AudioStateChangedEventArgs.cs
- Model3DGroup.cs
- XmlDsigSep2000.cs
- XmlSchemaValidationException.cs
- HtmlUtf8RawTextWriter.cs
- recordstatescratchpad.cs
- Control.cs
- PrivilegeNotHeldException.cs
- ClockGroup.cs
- HelpProvider.cs
- ComponentEditorPage.cs
- Set.cs
- typedescriptorpermissionattribute.cs
- NameSpaceExtractor.cs
- GeometryHitTestResult.cs