ObservableCollection Base Class With Expression Blend Designer Support – An Example Project

by Dean 19. January 2009 17:31

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

  1. My generic base collection class that provides all of the test data (CollectionBase.cs)
  2. My Domain/Business object – in this example, it’s going to be a ‘person’ object that represents employee data (Person.cs)
  3. My person-specific collection class that provides a data-binding target for Expression Blend design (PersonCollection.cs)

EmployeeInfoSolution

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)

AddRef

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.

EmployeeInfoSolutionBlend

 

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

SelectCLR

Select ‘PersonCollection’ and hit enter, you will now see a new entry in the Data section of the right tab panel

DataSourceAdded

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

AddToGrid

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

FinalDataGeid

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:

DateGridData

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

Tags: ,

Silverlight | DataBinding

Comments


January 23. 2009 01:30
trackback
Trackback from Community Blogs

Silverlight Cream for January 22, 2009 - 3 -- #494

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading



Most comments

Tom Tom
1 comments
Derek Lakin Derek Lakin
1 comments
gb United Kingdom
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010 ButtonChrome.com