The simplest way to do design-time ViewModels with MVVM and Blend.


 

The problem is this: You’ve created your Views and ViewModels, but when you view them in Blend, you either see nothing, or the data you see is not useful for testing what you want in the view. There are various ways to deal with this, including writing code (either in the ViewModel or in a service locator) to return different data at design time.

I’m going to demonstrate a different way that doesn’t involve code, and is very simple and most importantly: Malleable.

Assumptions/Prep:

  • I have a ViewModel class called “BooksViewModel” that supports the search UI and result-set. This has some non-trivial properties such as a collection of “Book” classes.
  • I have a View called “BooksView” that allows you to search for books, but I haven’t yet hooked up the data bindings (it’s easier to do after you create sample data).
  • I have no code to differentiate between design time and runtime. The code is geared purely towards runtime.

What we’ll do:

  1. Use Blend to create some purely fake sample data.
  2. Assign the fake data as the data-context of the control you want, in a design-time-only fashion.
  3. Create the bindings and play with the data.

 

The “Before” picture: A view showing very little:

image

 

Step 1: Create some fake data with Blend:

Go to the “Data” tab, and create sample data from a class:

image

Select your ViewModel as the class to base the sample data on. This is a giant time-saver:

image

A new folder + file will be created: SampleData\BooksSampleData.xaml. It’s pre-filled with fake data and ugly namespaces. For readability, I’ve done a find/replace on the namespaces. Here’s what I get:

<m:BooksViewModel
  xmlns:m="clr-namespace:MVVM_DesignTime_Test.ViewModels"
  IsSearching="True"
  SearchError="Vestibulum cras"
  SearchString="Lectus fringilla eros">
    <m:BooksViewModel.SearchResults>
        <m:Book Author="Aliquam aenean" Name="Curabitur maecenas class" Price="216.9"/>
        ......
        <m:Book Author="Nec non" Name="Dictum etiam" Price="920.1"/>
        <m:Book Author="Elit fermentum enim" Name="Erat fusce" Price="597.75"/>
    </m:BooksViewModel.SearchResults>
</m:BooksViewModel>

Two interesting things to notice about the above:

  • It automatically generated multiple entries for the collection (“SearchResults”), as well as generating properties for each item in that collection (“Book”).
  • Pretty much any class can be instantiated like this in XAML, so no matter how deep/complex the ViewModel and dependent Model objects, you should be able to play with them in the text editor.

 

Step 2: Assign the DataContext

This is where the magic happens. Look back at the Data tab, and see that this new sample data source is now listed:

image

Simply drag-drop this guy onto the control which should use it as the data context. The mouse cursor will display text explaining what it will do. In my case, I dragged it onto the LayoutRoot grid, since I wanted everything under that to use it. Once this is done, you’ll notice a new XAML attribute on that control:

  d:DataContext="{d:DesignData /SampleData/BooksSampleData.xaml}"

This is the magic, especially the “d:” namespace declaration, which you’ll notice is mentioned in the page’s XAML declaration as such:

  mc:Ignorable="d"

Basically, this tells everyone that they should ignore everything in the “d” namespace. But Blend chooses not to, and acts on it; this is why it works in design time without horking up the runtime.

 

Step 3: Create the data bindings

Now when you select the “Data Binding…” context-menu for a control’s property, it will show you the properties that come from this data context, which correspond to your ViewModel, with the correct names, types, etc:

image

And BAM – there’s the data:

image

 

Now what?

  • Clean up the crappy namespaces in the XAML to make things more readable.
  • Change the data to whatever you like using the XAML editor.
  • When you make changes and save, the UI will auto-adjust; this is so much quicker than editing code.
  • When you make changes to the ViewModel class, remember to change corresponding properties to your sample data.
  • You can have multiple sample data files for multiple ViewModels, and use them on the same page – just drag each one onto the control which should use it.
    • This is especially useful in pivot and panorama apps, where one page actually houses a whole app with multiple ViewModels.

 



Comments (4)

  1. Michael L Perry says:

    I've found that when I add a property to the View Model class, Blend does not always generate new data for it. This is particularly true with collection properties.

    My solution in the past has been to delete the sample data, recreate it, and then rebind it. Fortunately, once you rebind the top level everything else pops in. Unfortunately, this does not preserve any tweaks I might have made to the sample data, like turning lorem ipsum into a phone number.

    My solution now is to use an object data source. Since I'm using the real View Model, it is always up-to-date. It takes more work to set up, but I find that it provides a more realistic design-time experience. Details are posted at updatecontrols.net/…/mvvm_design_time_data.

  2. Michael Washington says:

    Great post. I have used this in many tutorials but I never explained what was going on. Also this demonstrates what a wonderful tool Blend is.

  3. Stefen says:

    Nothing happens when i drag the sample data to my controls, i tried this with listbox, gridview and radgridview each failing even when switching the sample data class still nothing …

  4. AviP says:

    @Stefen: Make sure you're dragging the right thing; check out the screenshot – there's actually an item in a tree control.

    When you're about to release the drag-drop you should get a tooltip indicating what you'll get. If you don't, you're prolly dragging the wrong thing.