MVVM and Designer Data

Aug 19
Posted by david.woods

Over the last week I have been playing around with Silverlight and the Model View View Model (MVVM) pattern that I have heard such great things about. So far it is a really nice way to separate the UI logic from the UI and make it easily testable.

One of the things I loved in Silverlight was the support for design time data. Design time data allowed you to specify dummy data that would appear in VS/Blend so that you could work with the UI with sample data. This saves so much time as now you don’t have to open the app, (possibly login), navigate to the area you are working on, and then see if you have it the way you want.

The challenge was now to combine MVVM and this dummy design time data. It is a lot simpler than I thought. I simply created a dummy View Model that inherited from my runtime VM and loaded it with sample data.

Runtime ViewModel:
public class SummaryViewModel : BaseViewModel
    {
        public int MoviesOwned { get; set; }
        public int MoviesCurrentlyRentedOut { get; set; }
        public ObservableCollection<Category> Categories { get; set; }

        private readonly MovieServiceClient _service;
        public SummaryViewModel()
        {
            _service = new MovieServiceClient();
            _service.GetAllCategoriesCompleted += GetAllCategoriesCompleted;
            if (!System.ComponentModel.DesignerProperties.IsInDesignTool)            
                _service.GetAllCategoriesAsync();
        }

        private void GetAllCategoriesCompleted(object sender, GetAllCategoriesCompletedEventArgs e)
        {
            Categories = e.Result;
            InvokePropertyChanged(“Categories”);
        }
    }

Design Time View Model:
  public class DesignTimeSummaryViewModelViewModel : SummaryViewModel
    {
        public DesignTimeSummaryViewModelViewModel()
        {
            Categories = new ObservableCollection<Category>();
            Categories.Add(new Category() { Name = “Design Time Test” }); ;
            Categories.Add(new Category() { Name = “Design Time Test 2″ }); ;
            Categories.Add(new Category() { Name = “Design Time Test 3″ }); ;
            MoviesOwned = 10;
            MoviesCurrentlyRentedOut = 5;
        }
    }

Summary.xaml view (designer info in orange, runtime in blue):
<UserControl x:Class=”MovieRental.UI.MainPage”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
    xmlns:d=”http://schemas.microsoft.com/expression/blend/2008″
    xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006″
    xmlns:local=”clr-namespace:MovieRental.UI.ViewModels”
    mc:Ignorable=”d”
    d:DesignHeight=”300″ d:DesignWidth=”400″
    d:DataContext=”{d:DesignInstance Type=local:DesignTimeSummaryViewModelViewModel,IsDesignTimeCreatable=True}”

    >
    <UserControl.Resources>

        <local:SummaryViewModel x:Key=”vm” />

    </UserControl.Resources>

    <UserControl.DataContext>

        <Binding Source=”{StaticResource vm}” />

    </UserControl.DataContext>

    <Grid x:Name=”LayoutRoot” Background=”White”>
        <StackPanel>
            <StackPanel Orientation=”Horizontal”>
                <TextBlock Text=”Movies Owned” />
                <TextBlock Text=”{Binding MoviesOwned}” Padding=”7,0,0,0″/>
        </StackPanel>
        <StackPanel Orientation=”Horizontal”>
                <TextBlock Text=”Movies Rented”/>
                <TextBlock Text=”{Binding MoviesCurrentlyRentedOut}” Padding=”7,0,0,0″ />
        </StackPanel>
            <ListBox ItemsSource=”{Binding Categories}” DisplayMemberPath=”Name”>
            </ListBox>
        </StackPanel>
    </Grid>
</UserControl>

So far this is working pretty good. The thing that surprised me is that the designer still runs the runtime ViewModels constructor so I had to put a check in around my WCF call to make sure it did not run in the designer via the      System.ComponentModel.DesignerProperties.IsInDesignTool line of code.

Filed Under: General

One Comment

  • The only trouble with the whole Blend sample data thing is if you’re working on a source controlled project in VS and Blend at the same time, and you do a Get Latest in VS that changes the sample data at all, Blend will asplode and you’ll have to at least close the solution, sometimes close Blend completely (and sometimes it just stalls anyway) to get it to work again.
    Other than that, yeah, Blend design time sample data’s great. heh.
    I’m working on a MVVM project right now and am still wrapping my head around it a little (sometimes it’s tricky to figure out how to accomplish certain complex scenarios with declarative binding, mainly), but I like where it seems to be going! Fortunately I’m working in the back-end more than the front-end so I don’t have to fully intuit the approaches required by the pattern immediately, I can watch it getting built up around me and in a few weeks I’m sure it’ll be second nature. :D

Leave a Reply

Your email address will not be published. Required fields are marked *

*