In my previous post showed how to create a lightweight collection class that can be used in expression blend enabling design-support for data bound control development.
In this post, I thought I’d expand on my previous writings and actually create a sample project from beginning to end – demonstrating how easy it is to use this solution.
Step 1 – Create Your Project (Programmers Job)
In VS2008, create a Silverlight application project – Im going to call mine EmployeeInfo for the purpose of this blog. I also need to create my data classes, So I’m going to create 3
- My generic base collection class that provides all of the test data (CollectionBase.cs)
- My Domain/Business object – in this example, it’s going to be a ‘person’ object that represents employee data (Person.cs)
- My person-specific collection class that provides a data-binding target for Expression Blend design (PersonCollection.cs)
The code for CollectionBase.cs and PersonCollection.cs is available in the previous post here
The code for the Person.cs code file is below
using System;
using System;
namespace EmployeeInfo
{
public class Person
{
public string Name { get; set; }
public DateTime Dob { get; set; }
public int EmployeeId { get; set; }
public double Salary { get; set; }
}
}
As you can see, my example Person class is pretty simple, but you can make it as complicated as you like.
Now, I know in my project Im going to want to use a Silverlight DataGrid control, so I know that I need to add an additional project reference for this, and it’s easier to do this while in Visual Studio. Simple click on ‘Add Reference’ in the solution explorer and select the System.Windows.Controls and System.Windows.Controls.Data references to the solution (see below)
Save all your files, lets move on to Blend.
Step 2 – Use Your Collection in Expression Blend
Open up the project in Blend and you’ll see the same code files in the blend project.
Now lets drop a DataGrid into our Page in order to demonstrate our example.
When ‘Design’ mode, click on the Asset Library button on the far left and select DataGrid from the available controls. Double click on the DataGrid button to add a DataGrid to your Page.
With the DataGrid selected in the Object and Timeline panel, go to the Properties tab on the right and set the Horizontal and Vertical Alignments to ‘Stretch (this will expand the DataGrid to fit it’s parent, giving us a surface for the DataGrid in the designer).
Next, lets start using our new Data classes.
On the project tab on the right hand side, click on the ‘+CLR Object’ button to popup the object data source creation panel
Select ‘PersonCollection’ and hit enter, you will now see a new entry in the Data section of the right tab panel
Now the final operation is to add this DataSource to our DataGrid, which simply requires us to drag and drop the new DataSource (as named ‘PersonCollection (Array)’ in above screenshot) onto the DataGrid. As soon as you do this you get a popup confirming where you want to attach the DataSource
Select ‘DataGrid’ and the select ‘ItemsSource’ when it asks what you’d like to bind to in you DataGrid.
Instantly you should see a DataGrid full of test data
As you can see – instant test data.
And now you can begin working on this grid in Blend – maybe hand-crank your column definitions, wire in your ValueConverters or re-template your headers etc.
(There's a neat trick with this solution, in that every time you re-build - Ctrl+Shift+B – you get new data, so you can keep rebuilding until you get the test data that suits you the most)
However, the test data is just random strings and numbers, which should be enough in most cases, but if not, then you can do the following
Step 3 (optional) – Refine Your Test Data
In the preceding code, the data was randomly generated, to get a more accurate version of the data available at design time we can override the BuildTestData() method, and inject our own test objects into the collection.
Here's an example:
public override void BuildTestData()
{
Add(new Person
{
Dob = new DateTime(1966, 12, 1),
EmployeeId = 1445667,
Name = "John Smith",
Salary = 45025
});
Add(new Person
{
Dob = new DateTime(1981, 7, 31),
EmployeeId = 3342556,
Name = "Dave Hanley",
Salary = 88343
});
Add(new Person
{
Dob = new DateTime(1977, 3, 5),
EmployeeId = 5544667,
Name = "Kunwar Singh",
Salary = 66500
});
Add(new Person
{
Dob = new DateTime(1972, 3, 1),
EmployeeId = 5688833,
Name = "James Madden",
Salary = 58332
});
Add(new Person
{
Dob = new DateTime(1980, 5, 9),
EmployeeId = 988776,
Name = "Harvey Sanders",
Salary = 77221
});
Add(new Person
{
Dob = new DateTime(1969, 8, 12),
EmployeeId = 665887,
Name = "Joshua Jones",
Salary = 34700
});
}
And now in Blend when we re-build we get this:
So, there we have the test data in Blend
Step 4 – Add The Real Data Feed When Ready
This part is really simple, and is demonstrated in the code below
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
Loaded += ControlLoaded;
}
private void ControlLoaded(object sender, RoutedEventArgs e)
{
service.GetEmployeesCompleted += (source, args) =>
{if (args.Error == null && !args.Cancelled) {
PersonGrid.ItemsSource = args.Result; }};
service.GetEmployeesAsync();
}
}
And there you have it
Finally, another great tip, if you want to override the BuildTestData() method, and already have a service that can provide plenty of data – and that is create a quick and dirty console application that retrieves a suitable number of objects from the service, then use the XmlSerializer to serialize the collection to an xml string. This can then be added to your test collection class and de-serialized to re-create the same data without needing any backend services.
Dean