Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / 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
- Baml2006SchemaContext.cs
- ContractTypeNameCollection.cs
- XmlSchemaDatatype.cs
- SerializerWriterEventHandlers.cs
- RequiredFieldValidator.cs
- ItemDragEvent.cs
- CookielessHelper.cs
- MenuEventArgs.cs
- ISFClipboardData.cs
- DiagnosticEventProvider.cs
- PreviewKeyDownEventArgs.cs
- HandoffBehavior.cs
- ListControlConvertEventArgs.cs
- EmptyTextWriter.cs
- BamlRecordReader.cs
- UdpDiscoveryEndpointElement.cs
- NavigatorOutput.cs
- SimpleWebHandlerParser.cs
- PartialTrustHelpers.cs
- CodeExporter.cs
- XamlDesignerSerializationManager.cs
- FixedStringLookup.cs
- DrawingCollection.cs
- DateTimeValueSerializer.cs
- Attributes.cs
- RegisteredArrayDeclaration.cs
- MetafileHeader.cs
- TableStyle.cs
- BuildProviderCollection.cs
- UpDownBase.cs
- MemoryPressure.cs
- ParameterElement.cs
- BamlVersionHeader.cs
- XmlILIndex.cs
- CommunicationObjectManager.cs
- View.cs
- unitconverter.cs
- XmlAutoDetectWriter.cs
- WindowsIdentity.cs
- cookiecollection.cs
- SafeFileMapViewHandle.cs
- PtsHelper.cs
- DataControlImageButton.cs
- ControlCodeDomSerializer.cs
- GeneralTransformGroup.cs
- AttributeProviderAttribute.cs
- XsdDataContractImporter.cs
- SspiNegotiationTokenAuthenticatorState.cs
- TextTreeNode.cs
- SerializationHelper.cs
- UpdateTranslator.cs
- DataControlImageButton.cs
- PerformanceCounterCategory.cs
- ConfigXmlText.cs
- Deserializer.cs
- FixedPage.cs
- path.cs
- Vector3D.cs
- ThicknessKeyFrameCollection.cs
- EventlogProvider.cs
- RtfNavigator.cs
- XPathPatternBuilder.cs
- StreamUpdate.cs
- AsymmetricKeyExchangeDeformatter.cs
- Utils.cs
- TreeWalker.cs
- Message.cs
- SqlUDTStorage.cs
- ObjectAssociationEndMapping.cs
- InstanceKey.cs
- MarshalByRefObject.cs
- JoinElimination.cs
- SpellerInterop.cs
- SectionRecord.cs
- HttpWrapper.cs
- RootBrowserWindowAutomationPeer.cs
- DragCompletedEventArgs.cs
- _ListenerRequestStream.cs
- BlurEffect.cs
- ManagementOptions.cs
- SectionVisual.cs
- ComplexLine.cs
- SelectionProviderWrapper.cs
- HttpRequestCacheValidator.cs
- KeyboardEventArgs.cs
- SecurityAttributeGenerationHelper.cs
- UInt64.cs
- TableLayoutPanel.cs
- PickBranchDesigner.xaml.cs
- Label.cs
- DrawingContext.cs
- ConsumerConnectionPointCollection.cs
- SetterBaseCollection.cs
- NetworkStream.cs
- MsmqProcessProtocolHandler.cs
- QueryCacheManager.cs
- LinkDesigner.cs
- PieceNameHelper.cs
- TCEAdapterGenerator.cs
- UIElementParagraph.cs