/// <summary> /// Simple registration, metadata, validation, and a read-only property /// key. Calling this version restricts the property such that it can /// only be set via the corresponding overload of DependencyObject.SetValue. /// </summary> public static DependencyPropertyKey RegisterReadOnly( string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback) { RegisterParameterValidation(name, propertyType, ownerType); PropertyMetadata defaultMetadata = null; if (typeMetadata != null && typeMetadata.DefaultValueWasSet()) { defaultMetadata = new PropertyMetadata(typeMetadata.DefaultValue); } else { defaultMetadata = AutoGeneratePropertyMetadata(propertyType, validateValueCallback, name, ownerType); } // We create a DependencyPropertyKey at this point with a null property // and set that in the _readOnlyKey field. This is so the property is // marked as requiring a key immediately. If something fails in the // initialization path, the property is still marked as needing a key. // This is better than the alternative of creating and setting the key // later, because if that code fails the read-only property would not // be marked read-only. The intent of this mildly convoluted code // is so we fail securely. DependencyPropertyKey authorizationKey = new DependencyPropertyKey(null); // No property yet, use null as placeholder. DependencyProperty property = RegisterCommon(name, propertyType, ownerType, defaultMetadata, validateValueCallback); property._readOnlyKey = authorizationKey; authorizationKey.SetDependencyProperty(property); if (typeMetadata == null) { // No metadata specified, generate one so we can specify the authorized key. typeMetadata = AutoGeneratePropertyMetadata(propertyType, validateValueCallback, name, ownerType); } // Authorize registering type for read-only access, create key. #pragma warning suppress 6506 // typeMetadata is never null, since we generate default metadata if none is provided. // Apply type-specific metadata to owner type only property.OverrideMetadata(ownerType, typeMetadata, authorizationKey); return(authorizationKey); }
/// <summary>Registers a dependency property with the specified property name, property type, owner type, property metadata, and a value validation callback for the property. </summary> /// <returns>A dependency property identifier that should be used to set the value of a public static readonly field in your class. That identifier is then used to reference the dependency property later, for operations such as setting its value programmatically or obtaining metadata.</returns> /// <param name="name">The name of the dependency property to register.</param> /// <param name="propertyType">The type of the property.</param> /// <param name="ownerType">The owner type that is registering the dependency property.</param> /// <param name="typeMetadata">Property metadata for the dependency property.</param> /// <param name="validateValueCallback">A reference to a callback that should perform any custom validation of the dependency property value beyond typical type validation.</param> public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback) { RegisterParameterValidation(name, propertyType, ownerType); PropertyMetadata defaultMetadata = null; if (typeMetadata != null && typeMetadata.DefaultValueWasSet()) { defaultMetadata = new PropertyMetadata(typeMetadata.DefaultValue); } DependencyProperty dependencyProperty = RegisterCommon(name, propertyType, ownerType, defaultMetadata, validateValueCallback); if (typeMetadata != null) { dependencyProperty.OverrideMetadata(ownerType, typeMetadata); } return(dependencyProperty); }
/// <summary>Registers a read-only dependency property, with the specified property type, owner type, property metadata, and a validation callback. </summary> /// <returns>A dependency property key that should be used to set the value of a static read-only field in your class, which is then used to reference the dependency property later.</returns> /// <param name="name">The name of the dependency property to register.</param> /// <param name="propertyType">The type of the property.</param> /// <param name="ownerType">The owner type that is registering the dependency property.</param> /// <param name="typeMetadata">Property metadata for the dependency property.</param> /// <param name="validateValueCallback">A reference to a user-created callback that should perform any custom validation of the dependency property value beyond typical type validation.</param> public static DependencyPropertyKey RegisterReadOnly(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback) { RegisterParameterValidation(name, propertyType, ownerType); PropertyMetadata propertyMetadata = null; propertyMetadata = ((typeMetadata == null || !typeMetadata.DefaultValueWasSet()) ? AutoGeneratePropertyMetadata(propertyType, validateValueCallback, name, ownerType) : new PropertyMetadata(typeMetadata.DefaultValue)); DependencyPropertyKey dependencyPropertyKey = new DependencyPropertyKey(null); DependencyProperty dependencyProperty = RegisterCommon(name, propertyType, ownerType, propertyMetadata, validateValueCallback); dependencyProperty._readOnlyKey = dependencyPropertyKey; dependencyPropertyKey.SetDependencyProperty(dependencyProperty); if (typeMetadata == null) { typeMetadata = AutoGeneratePropertyMetadata(propertyType, validateValueCallback, name, ownerType); } dependencyProperty.OverrideMetadata(ownerType, typeMetadata, dependencyPropertyKey); return(dependencyPropertyKey); }
private static DependencyProperty RegisterCommon(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback) { FromNameKey key = new FromNameKey(name, ownerType); lock (Synchronized) { if (PropertyFromName.Contains(key)) { throw new ArgumentException(SR.Get("PropertyAlreadyRegistered", name, ownerType.Name)); } } if (defaultMetadata == null) { defaultMetadata = AutoGeneratePropertyMetadata(propertyType, validateValueCallback, name, ownerType); } else { if (!defaultMetadata.DefaultValueWasSet()) { defaultMetadata.DefaultValue = AutoGenerateDefaultValue(propertyType); } ValidateMetadataDefaultValue(defaultMetadata, propertyType, name, validateValueCallback); } DependencyProperty dependencyProperty = new DependencyProperty(name, propertyType, ownerType, defaultMetadata, validateValueCallback); defaultMetadata.Seal(dependencyProperty, null); if (defaultMetadata.IsInherited) { dependencyProperty._packedData |= Flags.IsPotentiallyInherited; } if (defaultMetadata.UsingDefaultValueFactory) { dependencyProperty._packedData |= Flags.IsPotentiallyUsingDefaultValueFactory; } lock (Synchronized) { PropertyFromName[key] = dependencyProperty; } if (TraceDependencyProperty.IsEnabled) { TraceDependencyProperty.TraceActivityItem(TraceDependencyProperty.Register, dependencyProperty, dependencyProperty.OwnerType); } return(dependencyProperty); }
/// <summary> /// After parameters have been validated for OverrideMetadata, this /// method is called to actually update the data structures. /// </summary> private void ProcessOverrideMetadata( Type forType, PropertyMetadata typeMetadata, DependencyObjectType dType, PropertyMetadata baseMetadata) { // Store per-Type metadata for this property. Locks only on Write. // Datastructure guaranteed to be valid for non-locking readers lock (Synchronized) { if (DependencyProperty.UnsetValue == _metadataMap[dType.Id]) { _metadataMap[dType.Id] = typeMetadata; } else { throw new ArgumentException(SR.Format(SR.TypeMetadataAlreadyRegistered, forType.Name)); } } // Merge base's metadata into this metadata // CALLBACK typeMetadata.InvokeMerge(baseMetadata, this); // Type metadata may no longer change (calls OnApply) typeMetadata.Seal(this, forType); if (typeMetadata.IsInherited) { _packedData |= Flags.IsPotentiallyInherited; } if (typeMetadata.DefaultValueWasSet() && (typeMetadata.DefaultValue != DefaultMetadata.DefaultValue)) { _packedData |= Flags.IsDefaultValueChanged; } if (typeMetadata.UsingDefaultValueFactory) { _packedData |= Flags.IsPotentiallyUsingDefaultValueFactory; } }
/// <summary> /// Register a Dependency Property /// </summary> /// <param name="name">Name of property</param> /// <param name="propertyType">Type of the property</param> /// <param name="ownerType">Type that is registering the property</param> /// <param name="typeMetadata">Metadata to use if current type doesn't specify type-specific metadata</param> /// <param name="validateValueCallback">Provides additional value validation outside automatic type validation</param> /// <returns>Dependency Property</returns> public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback) { RegisterParameterValidation(name, propertyType, ownerType); // Register an attached property PropertyMetadata defaultMetadata = null; if (typeMetadata != null && typeMetadata.DefaultValueWasSet()) { defaultMetadata = new PropertyMetadata(typeMetadata.DefaultValue); } DependencyProperty property = RegisterCommon(name, propertyType, ownerType, defaultMetadata, validateValueCallback); if (typeMetadata != null) { // Apply type-specific metadata to owner type only property.OverrideMetadata(ownerType, typeMetadata); } return property; }
private void ProcessOverrideMetadata(Type forType, PropertyMetadata typeMetadata, DependencyObjectType dType, PropertyMetadata baseMetadata) { lock (Synchronized) { if (UnsetValue != _metadataMap[dType.Id]) { throw new ArgumentException(SR.Get("TypeMetadataAlreadyRegistered", forType.Name)); } _metadataMap[dType.Id] = typeMetadata; } typeMetadata.InvokeMerge(baseMetadata, this); typeMetadata.Seal(this, forType); if (typeMetadata.IsInherited) { _packedData |= Flags.IsPotentiallyInherited; } if (typeMetadata.DefaultValueWasSet() && typeMetadata.DefaultValue != DefaultMetadata.DefaultValue) { _packedData |= Flags.IsDefaultValueChanged; } if (typeMetadata.UsingDefaultValueFactory) { _packedData |= Flags.IsPotentiallyUsingDefaultValueFactory; } }
/// <summary> /// After parameters have been validated for OverrideMetadata, this /// method is called to actually update the data structures. /// </summary> private void ProcessOverrideMetadata( Type forType, PropertyMetadata typeMetadata, DependencyObjectType dType, PropertyMetadata baseMetadata) { // Store per-Type metadata for this property. Locks only on Write. // Datastructure guaranteed to be valid for non-locking readers lock (Synchronized) { if (DependencyProperty.UnsetValue == _metadataMap[dType.Id]) { _metadataMap[dType.Id] = typeMetadata; } else { throw new ArgumentException(SR.Get(SRID.TypeMetadataAlreadyRegistered, forType.Name)); } } // Merge base's metadata into this metadata // CALLBACK typeMetadata.InvokeMerge(baseMetadata, this); // Type metadata may no longer change (calls OnApply) typeMetadata.Seal(this, forType); if (typeMetadata.IsInherited) { _packedData |= Flags.IsPotentiallyInherited; } if (typeMetadata.DefaultValueWasSet() && (typeMetadata.DefaultValue != DefaultMetadata.DefaultValue)) { _packedData |= Flags.IsDefaultValueChanged; } if (typeMetadata.UsingDefaultValueFactory) { _packedData |= Flags.IsPotentiallyUsingDefaultValueFactory; } }
private static DependencyProperty RegisterCommon(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback) { FromNameKey key = new FromNameKey(name, ownerType); lock (Synchronized) { if (PropertyFromName.Contains(key)) { throw new ArgumentException(SR.Get(SRID.PropertyAlreadyRegistered, name, ownerType.Name)); } } // Establish default metadata for all types, if none is provided if (defaultMetadata == null) { defaultMetadata = AutoGeneratePropertyMetadata( propertyType, validateValueCallback, name, ownerType ); } else // Metadata object is provided. { // If the defaultValue wasn't specified auto generate one if (!defaultMetadata.DefaultValueWasSet()) { defaultMetadata.DefaultValue = AutoGenerateDefaultValue(propertyType); } ValidateMetadataDefaultValue( defaultMetadata, propertyType, name, validateValueCallback ); } // Create property DependencyProperty dp = new DependencyProperty(name, propertyType, ownerType, defaultMetadata, validateValueCallback); // Seal (null means being used for default metadata, calls OnApply) defaultMetadata.Seal(dp, null); if (defaultMetadata.IsInherited) { dp._packedData |= Flags.IsPotentiallyInherited; } if (defaultMetadata.UsingDefaultValueFactory) { dp._packedData |= Flags.IsPotentiallyUsingDefaultValueFactory; } // Map owner type to this property // Build key lock (Synchronized) { PropertyFromName[key] = dp; } if( TraceDependencyProperty.IsEnabled ) { TraceDependencyProperty.TraceActivityItem( TraceDependencyProperty.Register, dp, dp.OwnerType ); } return dp; }
/// <summary> /// Simple registration, metadata, validation, and a read-only property /// key. Calling this version restricts the property such that it can /// only be set via the corresponding overload of DependencyObject.SetValue. /// </summary> public static DependencyPropertyKey RegisterReadOnly( string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback ) { RegisterParameterValidation(name, propertyType, ownerType); PropertyMetadata defaultMetadata = null; if (typeMetadata != null && typeMetadata.DefaultValueWasSet()) { defaultMetadata = new PropertyMetadata(typeMetadata.DefaultValue); } else { defaultMetadata = AutoGeneratePropertyMetadata(propertyType,validateValueCallback,name,ownerType); } // We create a DependencyPropertyKey at this point with a null property // and set that in the _readOnlyKey field. This is so the property is // marked as requiring a key immediately. If something fails in the // initialization path, the property is still marked as needing a key. // This is better than the alternative of creating and setting the key // later, because if that code fails the read-only property would not // be marked read-only. The intent of this mildly convoluted code // is so we fail securely. DependencyPropertyKey authorizationKey = new DependencyPropertyKey(null); // No property yet, use null as placeholder. DependencyProperty property = RegisterCommon(name, propertyType, ownerType, defaultMetadata, validateValueCallback); property._readOnlyKey = authorizationKey; authorizationKey.SetDependencyProperty(property); if (typeMetadata == null ) { // No metadata specified, generate one so we can specify the authorized key. typeMetadata = AutoGeneratePropertyMetadata(propertyType,validateValueCallback,name,ownerType); } // Authorize registering type for read-only access, create key. #pragma warning suppress 6506 // typeMetadata is never null, since we generate default metadata if none is provided. // Apply type-specific metadata to owner type only property.OverrideMetadata(ownerType, typeMetadata, authorizationKey); return authorizationKey; }
private static DependencyProperty RegisterCommon(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback) { FromNameKey key = new FromNameKey(name, ownerType); lock (Synchronized) { if (PropertyFromName.Contains(key)) { throw new ArgumentException(SR.Format(SR.PropertyAlreadyRegistered, name, ownerType.Name)); } } // Establish default metadata for all types, if none is provided if (defaultMetadata == null) { defaultMetadata = AutoGeneratePropertyMetadata(propertyType, validateValueCallback, name, ownerType); } else // Metadata object is provided. { // If the defaultValue wasn't specified auto generate one if (!defaultMetadata.DefaultValueWasSet()) { defaultMetadata.DefaultValue = AutoGenerateDefaultValue(propertyType); } ValidateMetadataDefaultValue(defaultMetadata, propertyType, name, validateValueCallback); } // Create property DependencyProperty dp = new DependencyProperty(name, propertyType, ownerType, defaultMetadata, validateValueCallback); // Seal (null means being used for default metadata, calls OnApply) defaultMetadata.Seal(dp, null); if (defaultMetadata.IsInherited) { dp._packedData |= Flags.IsPotentiallyInherited; } if (defaultMetadata.UsingDefaultValueFactory) { dp._packedData |= Flags.IsPotentiallyUsingDefaultValueFactory; } // Map owner type to this property // Build key lock (Synchronized) { PropertyFromName[key] = dp; } if (TraceDependencyProperty.IsEnabled) { TraceDependencyProperty.TraceActivityItem( TraceDependencyProperty.Register, dp, dp.OwnerType); } return(dp); }