Creating a read-only dependency property is not that easy as one might think. It is not enough to just make the setter of the CLR property wrapper private:

public FooPropertyType Foo {
    get { return (MyPropertyType)GetValue(FooProperty); }
    private set { SetValue(FooProperty, value); }

Doing so is not enough because anyone can just use SetValue(FooProperty, ...) from outside of the class to set the property value.

The solution is to use the DependencyProperty.RegisterReadOnly method to register the property. This method returns a value of type DependencyPropertyKey - a private key that can be use to set the property.

Here is how the complete code of a read-only dependency property registration looks like:

public FooPropertyType Foo {
    get { return (FooPropertyType)GetValue(FooProperty); }
    private set { SetValue(FooPropertyKey, value); }
private static readonly DependencyPropertyKey FooPropertyKey =
    DependencyProperty.RegisterReadOnly("Foo", typeof(FooPropertyType),
                                         new UIPropertyMetadata(null));
public static readonly DependencyProperty FooProperty =

Note that FooPropertyKey is a private static field. This is important because if you make it public anyone from outside of the class will be able to change the property value.