If you are familiar with the Dependency Property system in WPF, you may find that create a Dependency Property that is supposed to be readonly is a bit different from the create a normal Dependency Property.
From this part on, I will use DP as a short name for Dependency Property.
The major difference is that when you create a readonly DP , you will use RegisterReadonly method as below.
public static DependencyPropertyKey RegisterReadOnly( string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata )
It is a static method of DependencyProperty class.
the return type of RegisterReadonly method is DependencyPropertyKey, which provide limited write access to read-only dependency property.
To get the value dp created by DependencyPropertyKey, you may do something like this :
public static readonly DependencyProperty ReadonlyProperty = ReadonlyPropertyKey.DependencyProperty; public double Readonly { get { return (double)GetValue(ReadonlyProperty); } }
in the code above, the ReadonlyPropertyKey is the key to registered dp.
As remarked by "RegisterReadonly" method, which I quoted as below.
Read-only dependency properties are a fairly typical scenario both in the existing API and for customization scenarios, because other WPF features might require a dependency property even if that property is not intended to be settable by callers. You can use the value of a read-only dependency property as the basis for other property system operations that take a dependency property, such as basing a Trigger on the dependency property in a style.
For more information on dependency property registration, see DependencyProperty.
You may want to
1. make internal or private access on the keys
2. expose (make public) the DependencyProperty (rather than the DependencypropertyKey which can be used to set the value of dp)
3. it is common practise to only provide a read accesor (do not provide a write accessor), or provide a restricted
so, for example,
it is normal you create a dpKey as follow
/* internal or private access to the key*/ internal static readonly dependencyPropertyKey ReadonlyKey = DependencyProperty.RegisterReadonly("Reaonly", typeof(string), type(OwnerClass), new PropertyMetadata(string.Empty));
and you will expose the DependencyProperty as follow.
ublic static readonly DependencyProperty ReadOnlyProperty
= ReadOnlyPropertyKey.DependencyProperty;
and then you might provide the accessor with appropriate protect level as follow.
public int ReadOnlyProp { get { return (int)GetValue(ReadOnlyProperty); } protected set { SetValue(ReadOnlyPropertyKey, value); } }
If you have registered some PropertyMetadata, it might look like this :
private static void OnReadOnlyPropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((OwnerClass)d).OnReadOnlyPropChanged(e); }
In the stackover flow post, it has the following example showing you how do you normally organize the readonly dp.
private static readonly DependencyPropertyKey ReadOnlyPropPropertyKey = DependencyProperty.RegisterReadOnly("ReadOnlyProp", typeof(int), typeof(OwnerClass), new FrameworkPropertyMetadata((int)0, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(OnReadOnlyPropChanged))); public static readonly DependencyProperty ReadOnlyPropProperty = ReadOnlyPropPropertyKey.DependencyProperty; public int ReadOnlyProp { get { return (int)GetValue(ReadOnlyPropProperty); } protected set { SetValue(ReadOnlyPropPropertyKey, value); } } private static void OnReadOnlyPropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((OwnerClass)d).OnReadOnlyPropChanged(e); }