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
- CompileXomlTask.cs
- WindowsListViewGroupSubsetLink.cs
- WebUtil.cs
- SQLDoubleStorage.cs
- GrammarBuilderPhrase.cs
- InputLanguage.cs
- TypeBuilderInstantiation.cs
- Type.cs
- HyperLinkStyle.cs
- TagPrefixAttribute.cs
- HighlightVisual.cs
- CryptoHandle.cs
- SafeFileHandle.cs
- GuidConverter.cs
- Attributes.cs
- CollectionViewGroupRoot.cs
- InkSerializer.cs
- XmlSchemaAttribute.cs
- CompositeFontParser.cs
- ColumnWidthChangingEvent.cs
- ProgressBarRenderer.cs
- Int16KeyFrameCollection.cs
- TimeoutHelper.cs
- FieldNameLookup.cs
- Vector3DCollectionConverter.cs
- MaskPropertyEditor.cs
- CompilationUnit.cs
- EventOpcode.cs
- BasicExpressionVisitor.cs
- CryptoKeySecurity.cs
- EllipseGeometry.cs
- DetailsViewDesigner.cs
- ToolBarButtonClickEvent.cs
- RoutingConfiguration.cs
- BitmapEffectInputConnector.cs
- SafeArrayTypeMismatchException.cs
- Ticks.cs
- RoleServiceManager.cs
- ResourceSet.cs
- SoapSchemaMember.cs
- PersonalizationEntry.cs
- WebPartMovingEventArgs.cs
- ParameterCollection.cs
- AuthenticatingEventArgs.cs
- BitConverter.cs
- DataServiceExpressionVisitor.cs
- KeyValueConfigurationElement.cs
- XamlTreeBuilder.cs
- TextChangedEventArgs.cs
- X509ServiceCertificateAuthenticationElement.cs
- AddInControllerImpl.cs
- MSG.cs
- X509SecurityToken.cs
- ConfigXmlComment.cs
- _ProxyChain.cs
- TypeLibConverter.cs
- SqlEnums.cs
- DataGridViewCellStyle.cs
- ServiceHttpHandlerFactory.cs
- HashSet.cs
- DataBinding.cs
- AssemblyUtil.cs
- XmlEventCache.cs
- IndicFontClient.cs
- SelectionItemPattern.cs
- SafeHandles.cs
- QueryStringParameter.cs
- HwndStylusInputProvider.cs
- PerformanceCounterLib.cs
- CurrentChangingEventArgs.cs
- HostProtectionException.cs
- MultiView.cs
- HttpResponse.cs
- SqlWebEventProvider.cs
- ReflectionServiceProvider.cs
- ThreadExceptionDialog.cs
- ContentType.cs
- LineServicesRun.cs
- CommonObjectSecurity.cs
- TextParagraphView.cs
- GroupDescription.cs
- RelationshipManager.cs
- ConnectivityStatus.cs
- QilNode.cs
- ThreadExceptionDialog.cs
- EndpointInfo.cs
- TextElement.cs
- OperationDescriptionCollection.cs
- PropertyItem.cs
- OrderPreservingPipeliningSpoolingTask.cs
- MethodInfo.cs
- ClientUtils.cs
- XmlFileEditor.cs
- ReadOnlyTernaryTree.cs
- RepeaterCommandEventArgs.cs
- WebPartDisplayMode.cs
- EncodingDataItem.cs
- ElementFactory.cs
- DataConnectionHelper.cs
- input.cs