Implementing DependencyProperty with a single attribute (and CciSharp)
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: