Wpf markupextension
1.Create a class library project named CustomMarkupExtension
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Markup; namespace CustomMarkupExtension { public class RandomExtension : MarkupExtension { readonly int from, to; public RandomExtension(int fromValue,int toValue) { from = fromValue; to= toValue; } public RandomExtension(int toValue) :this(0, toValue) { } static readonly Random _rnd = new Random(); public override object ProvideValue(IServiceProvider serviceProvider) { return (double)_rnd.Next(from, to); } } }
2.Rebuild as dll,and add reference in the main project
3.In the main wpf xaml view.
<Window x:Class="WpfApp8.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:WpfApp8" xmlns:libModels="http://WpfApp8_Models.com" xmlns:lib="http://mylibrary.com" xmlns:mext="clr-namespace:CustomMarkupExtension;assembly=CustomMarkupExtension" mc:Ignorable="d" Title="MainWindow" FontSize="20" Height="450" Width="800"> <StackPanel> <TextBlock FontSize="{mext:Random 100}" Text="Hello" x:Name="text1"/> <TextBlock x:Name="xt2" Text="{Binding FontSize,ElementName=text1}" FontSize="{Binding Text,ElementName=xt2}" /> </StackPanel> </Window>
Run
DepepdencyProperty implemented source code
#region Assembly WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 // location unknown // Decompiled with ICSharpCode.Decompiler 8.1.1.7464 #endregion using System.Collections; using System.ComponentModel; using System.Windows.Markup; using System.Windows.Threading; using MS.Internal; using MS.Internal.WindowsBase; using MS.Utility; namespace System.Windows; // // Summary: // Represents a property that can be set through methods such as, styling, data // binding, animation, and inheritance. [TypeConverter("System.Windows.Markup.DependencyPropertyConverter, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null")] [ValueSerializer(typeof(DependencyPropertyValueSerializer))] public sealed class DependencyProperty { private class FromNameKey { private string _name; private Type _ownerType; private int _hashCode; public FromNameKey(string name, Type ownerType) { _name = name; _ownerType = ownerType; _hashCode = _name.GetHashCode() ^ _ownerType.GetHashCode(); } public void UpdateNameKey(Type ownerType) { _ownerType = ownerType; _hashCode = _name.GetHashCode() ^ _ownerType.GetHashCode(); } public override int GetHashCode() { return _hashCode; } public override bool Equals(object o) { if (o != null && o is FromNameKey) { return Equals((FromNameKey)o); } return false; } public bool Equals(FromNameKey key) { if (_name.Equals(key._name)) { return _ownerType == key._ownerType; } return false; } } [Flags] private enum Flags { GlobalIndexMask = 0xFFFF, IsValueType = 0x10000, IsFreezableType = 0x20000, IsStringType = 0x40000, IsPotentiallyInherited = 0x80000, IsDefaultValueChanged = 0x100000, IsPotentiallyUsingDefaultValueFactory = 0x200000, IsObjectType = 0x400000 } // // Summary: // Specifies a static value that is used by the WPF property system rather than // null to indicate that the property exists, but does not have its value set by // the property system. // // Returns: // An unset value. This is effectively the result of a call to the System.Object // constructor. public static readonly object UnsetValue = new NamedObject("DependencyProperty.UnsetValue"); private string _name; private Type _propertyType; private Type _ownerType; private PropertyMetadata _defaultMetadata; private ValidateValueCallback _validateValueCallback; private DependencyPropertyKey _readOnlyKey; private Flags _packedData; internal InsertionSortMap _metadataMap; private CoerceValueCallback _designerCoerceValueCallback; internal static ItemStructList<DependencyProperty> RegisteredPropertyList = new ItemStructList<DependencyProperty>(768); private static Hashtable PropertyFromName = new Hashtable(); private static int GlobalIndexCount; internal static object Synchronized = new object(); private static Type NullableType = typeof(Nullable<>); // // Summary: // Gets the name of the dependency property. // // Returns: // The name of the property. public string Name => _name; // // Summary: // Gets the type that the dependency property uses for its value. // // Returns: // The System.Type of the property value. public Type PropertyType => _propertyType; // // Summary: // Gets the type of the object that registered the dependency property with the // property system, or added itself as owner of the property. // // Returns: // The type of the object that registered the property or added itself as owner // of the property. public Type OwnerType => _ownerType; // // Summary: // Gets the default metadata of the dependency property. // // Returns: // The default metadata of the dependency property. public PropertyMetadata DefaultMetadata => _defaultMetadata; // // Summary: // Gets the value validation callback for the dependency property. // // Returns: // The value validation callback for this dependency property, as provided for the // validateValueCallback parameter in the original dependency property registration. public ValidateValueCallback ValidateValueCallback => _validateValueCallback; // // Summary: // Gets an internally generated value that uniquely identifies the dependency property. // // // Returns: // A unique numeric identifier. public int GlobalIndex => (int)(_packedData & Flags.GlobalIndexMask); internal bool IsObjectType => (_packedData & Flags.IsObjectType) != 0; internal bool IsValueType => (_packedData & Flags.IsValueType) != 0; internal bool IsFreezableType => (_packedData & Flags.IsFreezableType) != 0; internal bool IsStringType => (_packedData & Flags.IsStringType) != 0; internal bool IsPotentiallyInherited => (_packedData & Flags.IsPotentiallyInherited) != 0; internal bool IsDefaultValueChanged => (_packedData & Flags.IsDefaultValueChanged) != 0; internal bool IsPotentiallyUsingDefaultValueFactory => (_packedData & Flags.IsPotentiallyUsingDefaultValueFactory) != 0; // // Summary: // Gets a value that indicates whether the dependency property identified by this // System.Windows.DependencyProperty instance is a read-only dependency property. // // // Returns: // true if the dependency property is read-only; otherwise, false. public bool ReadOnly => _readOnlyKey != null; internal DependencyPropertyKey DependencyPropertyKey => _readOnlyKey; internal CoerceValueCallback DesignerCoerceValueCallback { get { return _designerCoerceValueCallback; } set { if (ReadOnly) { throw new InvalidOperationException(SR.Get("ReadOnlyDesignerCoersionNotAllowed", Name)); } _designerCoerceValueCallback = value; } } internal static int RegisteredPropertyCount => RegisteredPropertyList.Count; internal static IEnumerable RegisteredProperties { get { DependencyProperty[] list = RegisteredPropertyList.List; foreach (DependencyProperty dependencyProperty in list) { if (dependencyProperty != null) { yield return dependencyProperty; } } } } // // Summary: // Registers a dependency property with the specified property name, property type, // and owner type. // // Parameters: // name: // The name of the dependency property to register. The name must be unique within // the registration namespace of the owner type. // // propertyType: // The type of the property. // // ownerType: // The owner type that is registering the dependency property. // // 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. public static DependencyProperty Register(string name, Type propertyType, Type ownerType) { return Register(name, propertyType, ownerType, null, null); } // // Summary: // Registers a dependency property with the specified property name, property type, // owner type, and property metadata. // // Parameters: // name: // The name of the dependency property to register. // // propertyType: // The type of the property. // // ownerType: // The owner type that is registering the dependency property. // // typeMetadata: // Property metadata for the dependency property. // // 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. public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata) { return Register(name, propertyType, ownerType, typeMetadata, null); } // // Summary: // Registers a dependency property with the specified property name, property type, // owner type, property metadata, and a value validation callback for the property. // // // Parameters: // name: // The name of the dependency property to register. // // propertyType: // The type of the property. // // ownerType: // The owner type that is registering the dependency property. // // typeMetadata: // Property metadata for the dependency property. // // validateValueCallback: // A reference to a callback that should perform any custom validation of the dependency // property value beyond typical type validation. // // 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. 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, and property metadata. // // Parameters: // name: // The name of the dependency property to register. // // propertyType: // The type of the property. // // ownerType: // The owner type that is registering the dependency property. // // typeMetadata: // Property metadata for the dependency property. // // 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. public static DependencyPropertyKey RegisterReadOnly(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata) { return RegisterReadOnly(name, propertyType, ownerType, typeMetadata, null); } // // Summary: // Registers a read-only dependency property, with the specified property type, // owner type, property metadata, and a validation callback. // // Parameters: // name: // The name of the dependency property to register. // // propertyType: // The type of the property. // // ownerType: // The owner type that is registering the dependency property. // // typeMetadata: // Property metadata for the dependency property. // // validateValueCallback: // A reference to a user-created callback that should perform any custom validation // of the dependency property value beyond typical type validation. // // 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. 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; } // // Summary: // Registers a read-only attached property, with the specified property type, owner // type, and property metadata. // // Parameters: // name: // The name of the dependency property to register. // // propertyType: // The type of the property. // // ownerType: // The owner type that is registering the dependency property. // // defaultMetadata: // Property metadata for the dependency property. // // 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. public static DependencyPropertyKey RegisterAttachedReadOnly(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata) { return RegisterAttachedReadOnly(name, propertyType, ownerType, defaultMetadata, null); } // // Summary: // Registers a read-only attached property, with the specified property type, owner // type, property metadata, and a validation callback. // // Parameters: // name: // The name of the dependency property to register. // // propertyType: // The type of the property. // // ownerType: // The owner type that is registering the dependency property. // // defaultMetadata: // Property metadata for the dependency property. // // validateValueCallback: // A reference to a user-created callback that should perform any custom validation // of the dependency property value beyond typical type validation. // // 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. public static DependencyPropertyKey RegisterAttachedReadOnly(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback) { RegisterParameterValidation(name, propertyType, ownerType); if (defaultMetadata == null) { defaultMetadata = AutoGeneratePropertyMetadata(propertyType, validateValueCallback, name, ownerType); } DependencyPropertyKey dependencyPropertyKey = new DependencyPropertyKey(null); DependencyProperty dependencyProperty = RegisterCommon(name, propertyType, ownerType, defaultMetadata, validateValueCallback); dependencyProperty._readOnlyKey = dependencyPropertyKey; dependencyPropertyKey.SetDependencyProperty(dependencyProperty); return dependencyPropertyKey; } // // Summary: // Registers an attached property with the specified property name, property type, // and owner type. // // Parameters: // name: // The name of the dependency property to register. // // propertyType: // The type of the property. // // ownerType: // The owner type that is registering the dependency property. // // 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. public static DependencyProperty RegisterAttached(string name, Type propertyType, Type ownerType) { return RegisterAttached(name, propertyType, ownerType, null, null); } // // Summary: // Registers an attached property with the specified property name, property type, // owner type, and property metadata. // // Parameters: // name: // The name of the dependency property to register. // // propertyType: // The type of the property. // // ownerType: // The owner type that is registering the dependency property. // // defaultMetadata: // Property metadata for the dependency property. This can include the default value // as well as other characteristics. // // 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. public static DependencyProperty RegisterAttached(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata) { return RegisterAttached(name, propertyType, ownerType, defaultMetadata, null); } // // Summary: // Registers an attached property with the specified property type, owner type, // property metadata, and value validation callback for the property. // // Parameters: // name: // The name of the dependency property to register. // // propertyType: // The type of the property. // // ownerType: // The owner type that is registering the dependency property. // // defaultMetadata: // Property metadata for the dependency property. This can include the default value // as well as other characteristics. // // validateValueCallback: // A reference to a callback that should perform any custom validation of the dependency // property value beyond typical type validation. // // 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. public static DependencyProperty RegisterAttached(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback) { RegisterParameterValidation(name, propertyType, ownerType); return RegisterCommon(name, propertyType, ownerType, defaultMetadata, validateValueCallback); } private static void RegisterParameterValidation(string name, Type propertyType, Type ownerType) { if (name == null) { throw new ArgumentNullException("name"); } if (name.Length == 0) { throw new ArgumentException(SR.Get("StringEmpty"), "name"); } if (ownerType == null) { throw new ArgumentNullException("ownerType"); } if (propertyType == null) { throw new ArgumentNullException("propertyType"); } } 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; } private static object AutoGenerateDefaultValue(Type propertyType) { object result = null; if (propertyType.IsValueType) { result = Activator.CreateInstance(propertyType); } return result; } private static PropertyMetadata AutoGeneratePropertyMetadata(Type propertyType, ValidateValueCallback validateValueCallback, string name, Type ownerType) { object obj = AutoGenerateDefaultValue(propertyType); if (validateValueCallback != null && !validateValueCallback(obj)) { throw new ArgumentException(SR.Get("DefaultValueAutoAssignFailed", name, ownerType.Name)); } return new PropertyMetadata(obj); } private static void ValidateMetadataDefaultValue(PropertyMetadata defaultMetadata, Type propertyType, string propertyName, ValidateValueCallback validateValueCallback) { if (!defaultMetadata.UsingDefaultValueFactory) { ValidateDefaultValueCommon(defaultMetadata.DefaultValue, propertyType, propertyName, validateValueCallback, checkThreadAffinity: true); } } internal void ValidateFactoryDefaultValue(object defaultValue) { ValidateDefaultValueCommon(defaultValue, PropertyType, Name, ValidateValueCallback, checkThreadAffinity: false); } private static void ValidateDefaultValueCommon(object defaultValue, Type propertyType, string propertyName, ValidateValueCallback validateValueCallback, bool checkThreadAffinity) { if (!IsValidType(defaultValue, propertyType)) { throw new ArgumentException(SR.Get("DefaultValuePropertyTypeMismatch", propertyName)); } if (defaultValue is Expression) { throw new ArgumentException(SR.Get("DefaultValueMayNotBeExpression")); } if (checkThreadAffinity && defaultValue is DispatcherObject dispatcherObject && dispatcherObject.Dispatcher != null) { if (!(dispatcherObject is ISealable sealable) || !sealable.CanSeal) { throw new ArgumentException(SR.Get("DefaultValueMustBeFreeThreaded", propertyName)); } Invariant.Assert(!sealable.IsSealed, "A Sealed ISealable must not have dispatcher affinity"); sealable.Seal(); Invariant.Assert(dispatcherObject.Dispatcher == null, "ISealable.Seal() failed after ISealable.CanSeal returned true"); } if (validateValueCallback != null && !validateValueCallback(defaultValue)) { throw new ArgumentException(SR.Get("DefaultValueInvalid", propertyName)); } } private void SetupOverrideMetadata(Type forType, PropertyMetadata typeMetadata, out DependencyObjectType dType, out PropertyMetadata baseMetadata) { if (forType == null) { throw new ArgumentNullException("forType"); } if (typeMetadata == null) { throw new ArgumentNullException("typeMetadata"); } if (typeMetadata.Sealed) { throw new ArgumentException(SR.Get("TypeMetadataAlreadyInUse")); } if (!typeof(DependencyObject).IsAssignableFrom(forType)) { throw new ArgumentException(SR.Get("TypeMustBeDependencyObjectDerived", forType.Name)); } if (typeMetadata.IsDefaultValueModified) { ValidateMetadataDefaultValue(typeMetadata, PropertyType, Name, ValidateValueCallback); } dType = DependencyObjectType.FromSystemType(forType); baseMetadata = GetMetadata(dType.BaseType); if (!baseMetadata.GetType().IsAssignableFrom(typeMetadata.GetType())) { throw new ArgumentException(SR.Get("OverridingMetadataDoesNotMatchBaseMetadataType")); } } // // Summary: // Specifies alternate metadata for this dependency property when it is present // on instances of a specified type, overriding the metadata that existed for the // dependency property as it was inherited from base types. // // Parameters: // forType: // The type where this dependency property is inherited and where the provided alternate // metadata will be applied. // // typeMetadata: // The metadata to apply to the dependency property on the overriding type. // // Exceptions: // T:System.InvalidOperationException: // An attempt was made to override metadata on a read-only dependency property (that // operation cannot be done using this signature). // // T:System.ArgumentException: // Metadata was already established for the dependency property as it exists on // the provided type. public void OverrideMetadata(Type forType, PropertyMetadata typeMetadata) { SetupOverrideMetadata(forType, typeMetadata, out var dType, out var baseMetadata); if (ReadOnly) { throw new InvalidOperationException(SR.Get("ReadOnlyOverrideNotAllowed", Name)); } ProcessOverrideMetadata(forType, typeMetadata, dType, baseMetadata); } // // Summary: // Supplies alternate metadata for a read-only dependency property when it is present // on instances of a specified type, overriding the metadata that was provided in // the initial dependency property registration. You must pass the System.Windows.DependencyPropertyKey // for the read-only dependency property to avoid raising an exception. // // Parameters: // forType: // The type where this dependency property is inherited and where the provided alternate // metadata will be applied. // // typeMetadata: // The metadata to apply to the dependency property on the overriding type. // // key: // The access key for a read-only dependency property. public void OverrideMetadata(Type forType, PropertyMetadata typeMetadata, DependencyPropertyKey key) { SetupOverrideMetadata(forType, typeMetadata, out var dType, out var baseMetadata); if (key == null) { throw new ArgumentNullException("key"); } if (ReadOnly) { if (key.DependencyProperty != this) { throw new ArgumentException(SR.Get("ReadOnlyOverrideKeyNotAuthorized", Name)); } VerifyReadOnlyKey(key); ProcessOverrideMetadata(forType, typeMetadata, dType, baseMetadata); return; } throw new InvalidOperationException(SR.Get("PropertyNotReadOnly")); } 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; } } [FriendAccessAllowed] internal object GetDefaultValue(DependencyObjectType dependencyObjectType) { if (!IsDefaultValueChanged) { return DefaultMetadata.DefaultValue; } return GetMetadata(dependencyObjectType).DefaultValue; } [FriendAccessAllowed] internal object GetDefaultValue(Type forType) { if (!IsDefaultValueChanged) { return DefaultMetadata.DefaultValue; } return GetMetadata(DependencyObjectType.FromSystemTypeInternal(forType)).DefaultValue; } // // Summary: // Returns the metadata for this dependency property as it exists on a specified // existing type. // // Parameters: // forType: // The specific type from which to retrieve the dependency property metadata. // // Returns: // A property metadata object. public PropertyMetadata GetMetadata(Type forType) { if (forType != null) { return GetMetadata(DependencyObjectType.FromSystemType(forType)); } throw new ArgumentNullException("forType"); } // // Summary: // Returns the metadata for this dependency property as it exists on the specified // object instance. // // Parameters: // dependencyObject: // A dependency object that is checked for type, to determine which type-specific // version of the dependency property the metadata should come from. // // Returns: // A property metadata object. public PropertyMetadata GetMetadata(DependencyObject dependencyObject) { if (dependencyObject != null) { return GetMetadata(dependencyObject.DependencyObjectType); } throw new ArgumentNullException("dependencyObject"); } // // Summary: // Returns the metadata for this dependency property as it exists on a specified // type. // // Parameters: // dependencyObjectType: // A specific object that records the dependency object type from which the dependency // property metadata is desired. // // Returns: // A property metadata object. public PropertyMetadata GetMetadata(DependencyObjectType dependencyObjectType) { if (dependencyObjectType != null) { int num = _metadataMap.Count - 1; if (num < 0) { return _defaultMetadata; } int key; object value; if (num == 0) { _metadataMap.GetKeyValuePair(num, out key, out value); while (dependencyObjectType.Id > key) { dependencyObjectType = dependencyObjectType.BaseType; } if (key == dependencyObjectType.Id) { return (PropertyMetadata)value; } } else if (dependencyObjectType.Id != 0) { do { _metadataMap.GetKeyValuePair(num, out key, out value); num--; while (dependencyObjectType.Id < key && num >= 0) { _metadataMap.GetKeyValuePair(num, out key, out value); num--; } while (dependencyObjectType.Id > key) { dependencyObjectType = dependencyObjectType.BaseType; } if (key == dependencyObjectType.Id) { return (PropertyMetadata)value; } } while (num >= 0); } } return _defaultMetadata; } // // Summary: // Adds another type as an owner of a dependency property that has already been // registered. // // Parameters: // ownerType: // The type to add as an owner of this dependency property. // // Returns: // A reference to the original System.Windows.DependencyProperty identifier that // identifies the dependency property. This identifier should be exposed by the // adding class as a public static readonly field. public DependencyProperty AddOwner(Type ownerType) { return AddOwner(ownerType, null); } // // Summary: // Adds another type as an owner of a dependency property that has already been // registered, providing dependency property metadata for the dependency property // as it will exist on the provided owner type. // // Parameters: // ownerType: // The type to add as owner of this dependency property. // // typeMetadata: // The metadata that qualifies the dependency property as it exists on the provided // type. // // Returns: // A reference to the original System.Windows.DependencyProperty identifier that // identifies the dependency property. This identifier should be exposed by the // adding class as a public static readonly field. public DependencyProperty AddOwner(Type ownerType, PropertyMetadata typeMetadata) { if (ownerType == null) { throw new ArgumentNullException("ownerType"); } FromNameKey key = new FromNameKey(Name, ownerType); lock (Synchronized) { if (PropertyFromName.Contains(key)) { throw new ArgumentException(SR.Get("PropertyAlreadyRegistered", Name, ownerType.Name)); } } if (typeMetadata != null) { OverrideMetadata(ownerType, typeMetadata); } lock (Synchronized) { PropertyFromName[key] = this; return this; } } // // Summary: // Returns a hash code for this System.Windows.DependencyProperty. // // Returns: // The hash code for this System.Windows.DependencyProperty. public override int GetHashCode() { return GlobalIndex; } // // Summary: // Determines whether a specified value is acceptable for this dependency property's // type, as checked against the property type provided in the original dependency // property registration. // // Parameters: // value: // The value to check. // // Returns: // true if the specified value is the registered property type or an acceptable // derived type; otherwise, false. public bool IsValidType(object value) { return IsValidType(value, PropertyType); } // // Summary: // Determines whether the provided value is accepted for the type of property through // basic type checking, and also potentially if it is within the allowed range of // values for that type. // // Parameters: // value: // The value to check. // // Returns: // true if the value is acceptable and is of the correct type or a derived type; // otherwise, false. public bool IsValidValue(object value) { if (!IsValidType(value, PropertyType)) { return false; } if (ValidateValueCallback != null) { return ValidateValueCallback(value); } return true; } internal void VerifyReadOnlyKey(DependencyPropertyKey candidateKey) { if (_readOnlyKey != candidateKey) { throw new ArgumentException(SR.Get("ReadOnlyKeyNotAuthorized")); } } internal bool IsValidValueInternal(object value) { if (ValidateValueCallback != null) { return ValidateValueCallback(value); } return true; } [FriendAccessAllowed] internal static DependencyProperty FromName(string name, Type ownerType) { DependencyProperty dependencyProperty = null; if (name != null) { if (ownerType != null) { FromNameKey fromNameKey = new FromNameKey(name, ownerType); while (dependencyProperty == null && ownerType != null) { SecurityHelper.RunClassConstructor(ownerType); fromNameKey.UpdateNameKey(ownerType); lock (Synchronized) { dependencyProperty = (DependencyProperty)PropertyFromName[fromNameKey]; } ownerType = ownerType.BaseType; } return dependencyProperty; } throw new ArgumentNullException("ownerType"); } throw new ArgumentNullException("name"); } // // Summary: // Returns the string representation of the dependency property. // // Returns: // The string representation of the dependency property. public override string ToString() { return _name; } internal static bool IsValidType(object value, Type propertyType) { if (value == null) { if (propertyType.IsValueType && (!propertyType.IsGenericType || !(propertyType.GetGenericTypeDefinition() == NullableType))) { return false; } } else if (!propertyType.IsInstanceOfType(value)) { return false; } return true; } private DependencyProperty(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback) { _name = name; _propertyType = propertyType; _ownerType = ownerType; _defaultMetadata = defaultMetadata; _validateValueCallback = validateValueCallback; Flags flags; lock (Synchronized) { flags = (Flags)GetUniqueGlobalIndex(ownerType, name); RegisteredPropertyList.Add(this); } if (propertyType.IsValueType) { flags |= Flags.IsValueType; } if (propertyType == typeof(object)) { flags |= Flags.IsObjectType; } if (typeof(Freezable).IsAssignableFrom(propertyType)) { flags |= Flags.IsFreezableType; } if (propertyType == typeof(string)) { flags |= Flags.IsStringType; } _packedData = flags; } internal static int GetUniqueGlobalIndex(Type ownerType, string name) { if (GlobalIndexCount >= 65535) { if (ownerType != null) { throw new InvalidOperationException(SR.Get("TooManyDependencyProperties", ownerType.Name + "." + name)); } throw new InvalidOperationException(SR.Get("TooManyDependencyProperties", "ConstantProperty")); } return GlobalIndexCount++; } } #if false // Decompilation log '14' items in cache ------------------ Resolve: 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Found single assembly: 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Load from: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\mscorlib.dll' ------------------ Resolve: 'System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Found single assembly: 'System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Load from: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Xaml.dll' ------------------ Resolve: 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Found single assembly: 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Load from: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.dll' ------------------ Resolve: 'Accessibility, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' Could not find by name: 'Accessibility, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' ------------------ Resolve: 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Found single assembly: 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Load from: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Core.dll' ------------------ Resolve: 'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Found single assembly: 'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Load from: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Xml.dll' ------------------ Resolve: 'System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' Could not find by name: 'System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' ------------------ Resolve: 'System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' Could not find by name: 'System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' #endif