Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / MS / Internal / ComponentModel / APCustomTypeDescriptor.cs / 1305600 / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- NetDispatcherFaultException.cs
- ConfigXmlCDataSection.cs
- Win32KeyboardDevice.cs
- TrustLevel.cs
- ApplicationBuildProvider.cs
- InstanceLockException.cs
- EventDescriptor.cs
- BitHelper.cs
- HtmlTitle.cs
- BinaryObjectReader.cs
- PathSegment.cs
- SpeechRecognizer.cs
- ObjectItemCollectionAssemblyCacheEntry.cs
- HealthMonitoringSectionHelper.cs
- ExpressionCopier.cs
- ProfileService.cs
- EFColumnProvider.cs
- TextBox.cs
- Blend.cs
- ToolStripSeparatorRenderEventArgs.cs
- BufferedGraphicsContext.cs
- TextServicesDisplayAttributePropertyRanges.cs
- Viewport3DAutomationPeer.cs
- HtmlForm.cs
- SystemDropShadowChrome.cs
- RuleElement.cs
- RightsManagementInformation.cs
- PersonalizationStateInfoCollection.cs
- PageAsyncTaskManager.cs
- EditorAttributeInfo.cs
- OrderedDictionaryStateHelper.cs
- GroupBox.cs
- Package.cs
- BooleanStorage.cs
- SchemaTableOptionalColumn.cs
- ZipPackage.cs
- Sequence.cs
- CalendarDay.cs
- DeviceContext.cs
- PropertyDescriptorGridEntry.cs
- BitmapEffectInput.cs
- TraceUtils.cs
- activationcontext.cs
- SecurityHelper.cs
- EventLogTraceListener.cs
- Animatable.cs
- KeyboardNavigation.cs
- TextTreeRootNode.cs
- ContentFileHelper.cs
- RenderingEventArgs.cs
- RegistryPermission.cs
- MeasureData.cs
- RelatedView.cs
- WinFormsComponentEditor.cs
- OracleSqlParser.cs
- PointAnimationClockResource.cs
- XslNumber.cs
- ToolboxItemLoader.cs
- GenericQueueSurrogate.cs
- TimeSpanParse.cs
- ToolStripGrip.cs
- InkCanvasSelection.cs
- ObjectReaderCompiler.cs
- ProcessModelSection.cs
- CodeGeneratorOptions.cs
- WorkflowLayouts.cs
- TemplateColumn.cs
- EntityDataSourceStatementEditorForm.cs
- SQLStringStorage.cs
- WebPartDescription.cs
- HtmlTextViewAdapter.cs
- CodeGeneratorOptions.cs
- OracleSqlParser.cs
- SynchronizationLockException.cs
- XamlStream.cs
- ModulesEntry.cs
- OAVariantLib.cs
- StreamReader.cs
- PageCatalogPart.cs
- FileCodeGroup.cs
- DataGridViewCellStyleChangedEventArgs.cs
- CodeIterationStatement.cs
- KeyedQueue.cs
- Pair.cs
- ToolStripDropDownItem.cs
- xmlglyphRunInfo.cs
- MarkedHighlightComponent.cs
- AssemblyAssociatedContentFileAttribute.cs
- BinaryParser.cs
- EntityRecordInfo.cs
- RoutedPropertyChangedEventArgs.cs
- SpellerInterop.cs
- DataServiceException.cs
- InputLanguageEventArgs.cs
- FilterableAttribute.cs
- DynamicMetaObject.cs
- ToolStripDropDownItem.cs
- XmlSchemaObject.cs
- TextRangeEditTables.cs
- ValueType.cs