Xaml design time data: an introduction to Radical.Design
I’m not a heavy user of the design time data basically because I do not usually design complex user interfaces that cannot be designed without design time data support, so blendability for me is not a strong requirement. On the other side I am a big fan of the technology and of the possibilities offered by the design time data, that some times can really save your life :-)
What does blendability mean?
The term was born with the arise of Microsoft Expression Blend (thus blendability) that is a tool for Xaml designers that promises to the designer to completely hide (take care of) the Xaml markup code giving to the designer all the required tools to design everything.
The problem is that Xaml UI are, most of the times, data driven, so the interfaces adapts itself to the shape of the data. That said is easy to understand that if in the designer we do not have the data, designing the UI can be really frustrating.
Blendability is the art of providing data at design time. We want to be able to have a class (a ViewModel) such as the following:
public class PersonViewModel : AbstractViewModel { String _firstName; public string FirstName { get { return this._firstName; } set { this._firstName = value; this.OnPropertyChanged( "FirstName" ); } } // other properties omitted for simplicity }
and a design time experience like this one:
Figure: the Visual Studio 2010 designer displaying a Xaml window with real data.
A design time experience where we have some data that help us to understand how the Xaml, we are designing, will behave at runtime.
Current state of the art
Currently there are 3 different approaches (well…2 since the first and the second we’ll see are technically the same):
- design your ViewModel so that it knows that it can run in the designer; there is an API that let’s you discover if you are running in the designer and thus the ViewModel can provide fake data at design time;
This approach has 2 main drawbacks: - You need to change your architecture/design to support something (the design time experience) that has nothing to do with the goal of the application;
- You need to have a public default constructor otherwise the designer cannot create an instance of the ViewModel at design time;
- use the ViewModelLocator approach, move the logic to detect the designer in the locator and return a completely different ViewModel when running in the designer;
Even this approach has drawbacks: - you need to use the *locator pattern, that personally I do not like at all;
- the design time view model must have exactly the same shape as the runtime view model, and as we’ll see, this can be a problem; this also has technical problems since you have to introduce interfaces for the view models or you need to be able to inherit from the runtime view model and override the relevant properties;
- you end up, even in this case, to inject, and change, and maintain, logic in your code in order to support the design time experience;
- use Radical.Design (available via NuGet) that has a completely different approach and solves all the outlined drawbacks of the other solutions;
In the next posts we’ll see how to achieve an amazing design time time experience using really strange stuff :-)
.m