In WPF, one needs to implement the DependencyProperty pattern to make properties bindable. It usually involves a lot of boiler plate code:
- adding a static field that names the depency property,
- adding the instance property to the type (and make sure you follow the naming convention),
- add validation methods and wire them in the dependency constructor
These are a number steps that need to be done again and again if you are building new WPF controls.
This is where a little transformation using CciSharp really helps with such boiler plate code. Using the DependencyAutoProperty mutator, you can define dependency properties with a single attribute. The rest is taken and validated by the compiler.
The simple scenario: Add [DependencyAutoProperty]
The rewritten code will contain a dependency property for the Value property, and will rewrite the value property getter and setters to use GetValue, SetValue instead.
Supporting default values
Default values can be specified in the DependencyProperty register method, so we want to support this as well through the DependencyAutoProperty constructor.
Callbacks can be passed in the constructor of DependencyProperty to validate the values of the property. To support this, we use a simple naming convention: if you specify the Validate = true constructor argument, the rewritter will look for a static “Validate” + property name method whose signature is Func<T, bool>, where T is the property type. The rewritter will make sure this method is used – or raise a compilation error if it is missing.
An interresting point here is that the callbacks passed in the DependencyProperty.Register method are untyped (Func<object, bool>) and the user needs to make the appropriate casts himself. This is taken care of by the rewritter: