Timo Korinth

2 Meter, 2 Mark

Alternative approach to Blends design time data

| 0 comments

Thankfully, most of the current Silverlight or WPF projects are implemented with MVVM, and and thus get the views data from their respective ViewModels. To properly design your views, it’s essential to work with Expression Blends design time sample data. Just with this support, it’s a real benefit to work on Expression Blends (or Visual Studios) design-surface. You do not have to compile and run your entire solution (which can be quite a long time) to check your changes. Unfortunately this feature is underestimated in many projects, and the way to test changes in design often leads to the workflow previously explained (compiling, running and navigating).

A solution to this problem is using sample data, provided by Expression Blend. Using this feature, you’ll get an easy and fast way to fill your data bound controls with content (at design time). In theory this is what you’ll get. Blend will generate sample data files from your ViewModel classes, by creating .xaml files in a subfolder called “SampleData”. The fun part is, that you’ll get to this point within seconds (Blend will automatically generate sample data for all public property types).

blenddatapanel

<DesignTimeData_ViewModel:DataViewModelSampleData
    xmlns:DesignTimeData_ViewModel="clr-namespace:DesignTimeData.ViewModel"
    Description="Dis maecenas"
    Header="Class man sed"
    Label="Cras curabitur" />

But the downside of this technique (especially in real projects) are the following points:

  1. You’ll get an extra folder (“SampleData”) with design time files in every project.
  2. If Blend creates a sample data file from your ViewModel class, you’ll have no influence on the generated sample data.
  3. There’s no easy way to update you sample data, if the class structure is changed.

So I would like to present an alternative approach to Blends design time data: If you would like to retain control of the sample data, you’ll have to create it on your own. The idea is to create a special class to hold the sample data. This will give you the chance to easily refactor or maintain your classes. If you got a ViewModel for instance, you could derive a new class and set or initialize all necessary properties accordingly.

On the top you can see the original ViewModel, and on the bottom it’s the derived class with sample data. There are two possible ways to set sample data on your properties: in the constructor of the derived class or in the overridden properties:

public class DataViewModel
{
    public virtual string Header { get; set; }
    public string Description { get; set; }
    public string Label { get; set; }
}

 

public class DataViewModelSampleData : DataViewModel
{
    public DataViewModelSampleData()
    {
        Description = "Beschreibung";
        Label = "Eingabe:";
    }

    public override string Header { get { return "Header"; } }
}

If you now change a property name for instance, the refactoring tool will automatically change the one on the sample data ViewModel (or at least the compiler will throw an error). Besides this, you could potentially define your sample data and use really long strings to check the text wrapping in your design, for example.

To use your derived sample data class in the designer, you simply have to apply the following line of code to your view:

d:DataContext="{d:DesignInstance vm:DataViewModelSampleData, IsDesignTimeCreatable=True}">

To get the real magic, you’ll have to set the attribute “IsDesignTimeCreatable” to true. In this case the empty constructor will be called and all your sample date (weather it’s been set in the constructor or in an overridden property) will be set.

There’s just one downside: As with the creation of .xaml files by Blend, you’ll blow up your projects with sample data ViewModels. If this doesn’t matter to you, stop reading ;-)

To everybody else I’ve got a little trick to hide your sample data classes. You can define dependencies in your .csproj file:

<Compile Include="ViewModel\DataViewModelSampleData.cs">
    <DependentUpon>DataViewModel.cs</DependentUpon>
</Compile>

With this trick you can achieve, that the derived ViewModel classes are hidden among the original classes:

dependentuponvs

Leave a Reply