public override bool Match(object value) { if (!(value is PropertyFilterAttribute)) { return(false); } PropertyFilterOptions other = ((PropertyFilterAttribute)value).options; PropertyFilterOptions common = other & options; return(common == options); }
public override bool Match(object value) { /*if (!(value is PropertyFilterAttribute)) * return false; * * PropertyFilterOptions other = ((PropertyFilterAttribute) value).options;*/ var propertyFilterAttribute = value as PropertyFilterAttribute; if (propertyFilterAttribute == null) { return(false); } PropertyFilterOptions other = propertyFilterAttribute._options; PropertyFilterOptions common = other & _options; return(common == _options); }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ #region Constructors /// <summary> /// Creates a new attribute. /// </summary> public PropertyFilterAttribute(PropertyFilterOptions filter) { _filter = filter; }
public PropertyFilterAttribute (PropertyFilterOptions filter) { options = filter; }
/// <summary> /// 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. /// </summary> 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 <PropertyDescriptor> filteredProps; if (filter == PropertyFilterOptions.SetValues) { LocalValueEnumerator localEnum = _instance.GetLocalValueEnumerator(); filteredProps = new List <PropertyDescriptor>(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 <PropertyDescriptor>(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); }
public PropertyFilterAttribute(PropertyFilterOptions filter) { throw new NotImplementedException (); }
/// <summary> /// 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. /// </summary> public PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // 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 no filter is set, or if the only filter is for "invalid" properties, // there's no work to do. if (filter == PropertyFilterOptions.None || filter == PropertyFilterOptions.Invalid) { return(PropertyDescriptorCollection.Empty); } // Value used during filtering. Because direct properties are always // returned for .Valid and .All, the only case we're directly interested // in is when filter exactly equals SetValues. DependencyObject filterValue; if (filter == PropertyFilterOptions.SetValues) { if (_instance == null) { return(PropertyDescriptorCollection.Empty); } filterValue = (DependencyObject)TypeDescriptor.GetAssociation(_objectType, _instance); } else { filterValue = null; } // Note: For a property filter of "SetValues" it would be ideal if we could use // DependencyObject's GetLocalValueEnumerator. Unfortunately, we can't: // // * We still need to scan properties to get the property descriptor that // matches the DP. // // * The enumerator would skip CLR properties that have no backing DP. // // We can still do some optimizations. // First, have we already discovered properties for this type? PropertyDescriptorCollection properties = (PropertyDescriptorCollection)_typeProperties[_objectType]; if (properties == null) { properties = CreateProperties(); lock (_typeProperties) { _typeProperties[_objectType] = properties; } } // 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. if ((filter & _anySet) == _anySet || (filter & _anyValid) == _anyValid) { return(properties); } // The filter specifies either set or unset values. Debug.Assert((filter & _anySet) == filter, "There is a filtering case we did not account for"); List <PropertyDescriptor> newDescriptors = null; int cnt = properties.Count; for (int idx = 0; idx < cnt; idx++) { PropertyDescriptor prop = properties[idx]; bool shouldSerialize = prop.ShouldSerializeValue(filterValue); bool addProp = shouldSerialize ^ ((filter & _anySet) == PropertyFilterOptions.UnsetValues); if (!addProp) { // Property should be removed. Make sure our newDescriptors array is // up to date for where we need to be if (newDescriptors == null) { newDescriptors = new List <PropertyDescriptor>(cnt); for (int i = 0; i < idx; i++) { newDescriptors.Add(properties[i]); } } } else if (newDescriptors != null) { newDescriptors.Add(prop); } } if (newDescriptors != null) { properties = new PropertyDescriptorCollection(newDescriptors.ToArray(), true); } return(properties); }
public PropertyFilterAttribute(PropertyFilterOptions filter) : this() { _options = filter; }