If you’ve written your own custom attached property in WPF you may come across the following error when you try to look at a Window, Page or UserControl that attempts to use the attached property in the WPF designer in Visual Studio 2008:
The Property '[your custom attached property name]' is read-only and cannot be changed
The puzzling thing is that you can get this error message even if your attached property is not defined as read-only, and has a setter and isn’t registered as read-only in the Property Meta-data. Even more confusingly the property can seem fine and working correctly at run-time.
So what’s going on? Although the error message is a little cryptic the error is caused by a type mismatch between the property type of the dependency property (when it is registered) and the second parameter accepted by the “Set[YourPropertyName]” method that is defined when creating an attached property. For example if you’ve registered an attached property like this:
public static readonly DependencyProperty MyCustomProperty =
DependencyProperty.RegisterAttached("MyCustom", typeof(MyOtherType), typeof(MyType));
The property meta-data system expects that when you set this attached property the value will be of MyOtherType (the second type parameter is the type that "owns" the dependency property, usually the type you declare the DP in). Type WPF designer is aware of this, for example if you attempt to assign this property in XAML from a string and no appropriate converter from string to MyOtherType is present it shows an error.
However as part of your attached property declaration you are also obliged to create "Get[PropertyName]" and "Set[PropertyName]" wrapper methods for getting and setting the attached properties.
public static void SetMyCustom(DependencyObject depObj, TheWrongType value)
If we include the wrong type as the second parameter in one of these declarations – in this case a type that is not assignable from MyOtherType - this isn’t a compile time error (because these methods aren’t part of any interface we’re implementing or generic type) and may work fine at run-time if that code path isn’t called (I believe that XAML bypasses the property wrappers). The designer does pick up on the discrepancy, and considers that type dependency property is read-only because it couldn’t find an appropriately typed "Set[YourPropertyName]” method. Of course this error is easy to resolve once you know the cause, by changing the type of the second parameter to be the same as, or assignable from the type that was used when you declared the dependency property.