How to make Databinding type safe and support refactoring?

Viewed 23046

When I wish to bind a control to a property of my object, I have to provide the name of the property as a string. This is not very good because:

  1. If the property is removed or renamed, then I don’t get a compiler warning.
  2. If a rename the property with a refactoring tool, then it is likely the data binding will not be updated.
  3. If the type of the property is wrong, e.g. binding an integer to a date chooser, then I don’t get an error until runtime.

Is there a design-pattern that gets round this, but still has the ease of use of data-binding?

(This is a problem in WinForms, ASP.NET, and WPF and possibly other systems.)

I have now found "workarounds for nameof() operator in C#: typesafe databinding" that also has a good starting point for a solution.

If you are willing to use a post processor after compiling your code, then NotifyPropertyWeaver is worth looking at.


Does anyone know of a good solution for WPF when the bindings are done in XML rather than C#?

8 Answers

One way to get feedback if your bindings are broken, is to create a DataTemplate and declare its DataType to be the type of the ViewModel that it binds to e.g. if you have a PersonView and a PersonViewModel you would do the following:

  1. Declare a DataTemplate with DataType = PersonViewModel and a key (e.g. PersonTemplate)

  2. Cut all PersonView xaml and paste it into the data template (which ideally can just be at the top of the PersonView.

3a. Create a ContentControl and set the ContentTemplate = PersonTemplate and bind its Content to the PersonViewModel.

3b. Another option is to not give a key to the DataTemplate and not set the ContentTemplate of the ContentControl. In this case WPF will figure out what DataTemplate to use, since it knows what type of object you are binding to. It will search up the tree and find your DataTemplate and since it matches the type of the binding, it will automatically apply it as the ContentTemplate.

You end up with essentially the same view as before, but since you mapped the DataTemplate to an underlying DataType, tools like Resharper can give you feedback (via Color identifiers - Resharper-Options-Settings-Color Identifiers) as to wether your bindings are broken or not.

You still won't get compiler warnings, but can visually check for broken bindings, which is better than having to check back and forth between your view and viewmodel.

Another advantage of this additional information you give, is, that it can also be used in renaming refactorings. As far as I remember Resharper is able to automatically rename bindings on typed DataTemplates when the underlying ViewModel's property name is changed and vice versa.

C# Markup seems to be solving the same set of problems, hence I am adding this answer as a pointer to help the current generation of programmers.

Xamarin.Forms 4.6 introduced C# Markup, a set of fluent helpers and classes that aim to make UI development in C# a joy.

C# Markup helps developers write concise declarative UI markup and cleanly separate it from UI logic, all in C#. Developers get to enjoy C#’s first-class IDE support when writing markup. A single language for markup and logic reduces friction, markup scattering and cognitive load; there is less or no need for language bridging mechanisms like separate converters, styles, resource dictionaries, behaviours, triggers and markup extensions

Related