When developing a solution using WPF or Silverlight, there are normally designers working in Blend and developers working with them in Visual Studio 2010. Often it is impractical for designers to use data from live systems (e.g. they don’t want to install SQL etc.) but they need data to flesh out the user interface so that they can style it and edit templates. For example a ListBox with no data is difficult to style in Blend, and certainly impossible to visualise. For this reason there is often a need to provide design time data that mimics the real runtime data.
The first cut approach to this is to put the mock data into XML files and then parse them into Plain-Old CLR Objects (POCOs), but this requires writing and maintaining an XML parser in your application. You’ve probably already realised that the XAML parser is pretty good at creating POCOs from XML – it is what it does for a living – so a far better approach than plain XML files is to create your POCO object graph through XAML and let the Silverlight/WPF XAML parser do the heavy lifting. You can then bind your user interface to this dummy data and get all your databindings correct and working, then switch it out at runtime for the real thing. Indeed this approach has been adopted by the Blend team, and there is UI support for this in Blend (the DATA tab) to allow you to create, edit and maintain the tree of design time data.
However, this situation isn’t ideal as you have a graph of dummy data which is included in your application at runtime but not used (it is only used during design time). Enter the DesignData markup extension and build action.
You’ve probably noticed that Blend adds the following namespace declarations to your XAML files:
mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
so what’s this all about? Well this is a pretty neat feature that allows Blend to set properties and attributes that are ignored at runtime. You’ve probably seen:
d:DesignHeight="350" d:DesignWidth="525"
which hints to Blend what size to draw a control at when viewed in the designer, without affecting runtime layout. Pretty neat! Well the DesignData markup extension takes this a step further.
To use DesignData, first create, as normal, your POCO objects that will hold your data in your view model. You should implement INotifyPropertyChanged so that your bindings update when the data changes. I am going to use the classic Person object as an example:
Next, in order to use DesignData, create a separate standalone XAML file that defines your view model:
<Persons xmlns="clr-namespace:WpfApplication5">
<Person PersonName="Joe Soap" Age="21" PhoneNumber="0118 909 1234"/>
<Person PersonName="Fred Bloggs" Age="35" PhoneNumber="0118 909 4321"/>
<Person PersonName="Bill Gates" Age="46" PhoneNumber="0118 909 1111"/>
<Person PersonName="Steve Jobs" Age="40" PhoneNumber="0118 909 2222"/>
</Persons>
Now set the build action in VS2010 for this file to DesignData:
Read more: MCS UK Solution Development Team
The first cut approach to this is to put the mock data into XML files and then parse them into Plain-Old CLR Objects (POCOs), but this requires writing and maintaining an XML parser in your application. You’ve probably already realised that the XAML parser is pretty good at creating POCOs from XML – it is what it does for a living – so a far better approach than plain XML files is to create your POCO object graph through XAML and let the Silverlight/WPF XAML parser do the heavy lifting. You can then bind your user interface to this dummy data and get all your databindings correct and working, then switch it out at runtime for the real thing. Indeed this approach has been adopted by the Blend team, and there is UI support for this in Blend (the DATA tab) to allow you to create, edit and maintain the tree of design time data.
However, this situation isn’t ideal as you have a graph of dummy data which is included in your application at runtime but not used (it is only used during design time). Enter the DesignData markup extension and build action.
You’ve probably noticed that Blend adds the following namespace declarations to your XAML files:
mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
so what’s this all about? Well this is a pretty neat feature that allows Blend to set properties and attributes that are ignored at runtime. You’ve probably seen:
d:DesignHeight="350" d:DesignWidth="525"
which hints to Blend what size to draw a control at when viewed in the designer, without affecting runtime layout. Pretty neat! Well the DesignData markup extension takes this a step further.
To use DesignData, first create, as normal, your POCO objects that will hold your data in your view model. You should implement INotifyPropertyChanged so that your bindings update when the data changes. I am going to use the classic Person object as an example:
Next, in order to use DesignData, create a separate standalone XAML file that defines your view model:
<Persons xmlns="clr-namespace:WpfApplication5">
<Person PersonName="Joe Soap" Age="21" PhoneNumber="0118 909 1234"/>
<Person PersonName="Fred Bloggs" Age="35" PhoneNumber="0118 909 4321"/>
<Person PersonName="Bill Gates" Age="46" PhoneNumber="0118 909 1111"/>
<Person PersonName="Steve Jobs" Age="40" PhoneNumber="0118 909 2222"/>
</Persons>
Now set the build action in VS2010 for this file to DesignData:
Now you have a design time object graph! Its as simple as that. This will not be loaded or created at runtime, it is not part of your running application.
In order to use this graph, you can set the d:DataContext anywhere in your application, using the DesignData markup extension and specifying the name of your data file. Note that this only affects the DataContext at design time, not the runtime DataContext. Also note that you need “..\” in your path if you are using Silverlight.
<Grid>
<ItemsControl d:DataContext="{d:DesignData Source=DesignTimeData.xaml}" ItemsSource="{Binding .}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding PersonName}"/>
Read more: MCS UK Solution Development Team