The source code for this article can be downloaded here. You can view a live sample of the grid in action here.
This article builds on Part 1 where we used ASP.Net AJAX to get a list of employees and then format then with Xaml to add them to our data grid. Please refer back to Part 1 for all the requirements to get this running since we will be using the same database and project.
A Slightly Different Approach
In Part 1 we used ASP.Net AJAX to get an array of employee objects which we then formatted as Xaml using a template after which we positioned each employee canvas on a simulated grid. This works pretty well, but I wanted to demonstrate a slightly different approach to getting the Xaml for each employee. In this article we will make use of the downloader object to download the Xaml for each employee and the formatting of the Xaml will be done on the server using XSLT.
The approach of using the downloader object is probably best suited for applications where there is a lot of Xaml or there is a lot of formatting that needs to be done to the xaml (like replacing values). In this case it might make a lot of sense to push this task down to the server instead of performing it on the client's machine. However, since this may require more data to be transferred over the wire it could potentially slow things down for clients with slower connection. So both approaches have benefits and drawbacks.
Step 1: Get the Employee IDs
Diving into the code, the first step will be getting the list of employees from the server. To do this we will make use of ASP.Net AJAX again. In the code I created another web service method called GetEmployeeIDs which simply returns an array of integers of all the employee IDs. We call this method using ASP.Net AJAX just as we called GetEmployees in the previous version. We will store this list in our javascript grid object and use it to pull the Xaml for each employee. Below is the call to get the Employee IDs:
EmployeeService.GetEmployeeIDs(delegate(this, this.loadEmployees));
The loadEmployees method of the grid object stores the list of IDs and then calls the startDownload method of the grid object.
Step 2: Download the Xaml
In order to allow the grid object to download the Xaml for each employee we need to create a HTTP handler to do the job. Instead of using a find/replace method of formatting the Xaml with the employee specific information I decided to take the XSLT route since the final result is XML. The first step, however, is to get the employee data in an XML format. To do this I created another method on the EmployeeData object that makes the following SQL Query and returns the result as a string:
select EmployeeID, LastName, FirstName, Title from Employees where EmployeeID = @empID for xml auto
By adding the for xml auto to the end of the statement we will get our results in XML format which will look like:
<Employees EmployeeID="1" LastName="Davolio" FirstName="Nancy" Title="Sales Rep" />
Now we can run this through our XSLT to create the output Xaml that we want. You can view the XSLT here.
Our HTTP handler just takes the XML and transforms it using our XSL and then write it to the output stream. You can view the resulting Xaml here.
*Note: you might notice that I create a new downloader object for each download. I started out using the same object each time but it kept crashing IE so I think there is some kind of bug. Creating a new object each time seemed to solve the problem.
Step 3: Add the Xaml to the Canvas
Once we've download the Xaml we just add it to the canvas and set the Canvas.Left and Canvas.Top properties to position it on the grid.
var empXaml = this.control.createFromXamlDownloader(sender);
empXaml["Canvas.Top"] = this.top;
empXaml["Canvas.Left"] = this.left;
this.canvas.children.add(empXaml);
The top and left properties are incremented each time using the incrementMargins method of the grid object. Next we either download the next employee or if we are done we hide the progress bar which I've added since the last example.
Next Steps
Just like last time I've left out quite a few things. Some of them I plan to implement in Part 3 which I'm working on now. But others, like mouse over effects and better images, are left for you to do. Have fun!