Wednesday, 20 February 2008

Silverlight Progress in an AJAXed GridView

This is a quick article on combining Silverlight and AJAX together to make richer user experiences for your existing Web Applications.

There are three parts to this sample:


  • The first part is building a standard asp.net gridview that binds to an xml file, and making it run under ajax.

  • The second part is about creating a simple silverlight progress indicator.

  • The third part is about combining the 2 samples together to make a datagrid which uses Silverlight as its progress indicator, rather than HTML.



Part One - Building a simple databound ajax gridview

1) Create a new website in ASP.NET
2) Create an Xml File (called mydata.xml) and drop it in the App_Data folder. My Xml is below:



<?xml version="1.0" encoding="utf-8" ?>
<Items>
<Item Name="Item1"/>
<Item Name="Item2"/>
<Item Name="Item3"/>
<Item Name="Item4"/>
<Item Name="Item5"/>
<Item Name="Item6"/>
<Item Name="Item7"/>
<Item Name="Item8"/>
<Item Name="Item9"/>
<Item Name="Item10"/>
<Item Name="Item11"/>
<Item Name="Item12"/>
<Item Name="Item13"/>
<Item Name="Item14"/>
<Item Name="Item15"/>
</Items>


3) Drop an XmlDataSource onto the page, and set the datafile



<asp:xmldatasource runat="server" id="itemsDataSource" datafile="~/App_Data/MyData.xml"></asp:xmldatasource>


4) Drop a gridview onto the page and set the datasource



<asp:GridView ID="GridView1" runat="server" DataSourceID="itemsDataSource" AllowPaging="True" PageSize="5" OnDataBinding="GridView1_DataBinding"></asp:GridView>


5) Add some code to send the page to sleep for a few seconds on databind



protected void GridView1_DataBinding(object sender, EventArgs e)
{
if (IsPostBack)
{
System.Threading.Thread.Sleep(5000);
}
}


6) You should now be able to run the sample on your site
7) If all is okay, we can now ajaxify it, so drop a scriptmanager onto the page, drop an UpdatePanel and UpdateProgress on the page
8) Stick the gridview within the update panel, and put a message like Hello World in the Update progress. You should now have some like the following:



<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" DataSourceID="itemsDataSource" AllowPaging="True"
PageSize="5" OnDataBinding="GridView1_DataBinding">
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
Hello World
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</form>
</body>
<asp:xmldatasource runat="server" id="itemsDataSource" datafile="~/App_Data/MyData.xml"></asp:xmldatasource>
</html>


Part 2 - Creating the Silverlight Page (1.1, but 1.0 will also work)

1) Add a silverlight project to your solution
2) Modify the Xaml to the following (this will create a rotating label with the text "Please Wait"



<Canvas x:Name="parentCanvas"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="Page_Loaded"
x:Class="MySilverlightApplication.Page;assembly=ClientBin/MySilverlightApplication.dll"
Width="150"
Height="150"
Background="White"
>
<Canvas.Triggers>
<EventTrigger>
<BeginStoryboard>
<Storyboard Storyboard.TargetName="myRotate"
Storyboard.TargetProperty="Angle"
RepeatBehavior="Forever"
>
<DoubleAnimation From="0" To="360" Duration="0:0:05"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
<TextBlock x:Name="myTextBlock" Text="Please Wait" Canvas.Left="25" Canvas.Top="50">
<TextBlock.RenderTransform>
<RotateTransform x:Name="myRotate" Angle="0" CenterX="30" CenterY="10"/>
</TextBlock.RenderTransform>
</TextBlock>
</Canvas>


You should now be able to run your project and all will be fine and dandy.

Part 3 - Integrating the two together

1) On your website, click "Add Silverlight Link", and click on your Silverlight project
2) Copy the silverlight.js file to your website
3) Copy TestPage.html.js to your website and rename it to Default.aspx.js
4) Comment out the section of the Default.aspx.js which does the document.body.onload, your Default.aspx.js file should now look like this



// JScript source code

//contains calls to silverlight.js, example below loads Page.xaml
function createSilverlight()
{
Silverlight.createObjectEx({
source: "Page.xaml",
parentElement: document.getElementById("SilverlightControlHost"),
id: "SilverlightControl",
properties: {
width: "100%",
height: "100%",
version: "1.1",
enableHtmlAccess: "true"
},
events: {}
});

// // Give the keyboard focus to the Silverlight control by default
// document.body.onload = function() {
// var silverlightControl = document.getElementById('SilverlightControl');
// if (silverlightControl)
// silverlightControl.focus();
// }

}


5) Modify the head tag of your default.aspx to include the javascript files



<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="Default.aspx.js"></script>
<style type="text/css">
.silverlightHost
{
width: 150px;
height: 150px;
}
</style>
</head>


6) Modify the Update Progress to include your silverlight control



<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
<div id="SilverlightControlHost" class="silverlightHost">

<script type="text/javascript">
createSilverlight();
</script>

</div>
</ProgressTemplate>
</asp:UpdateProgress>


7) You should now be able to run your website and have a Silverlight progress indicator.

You will obviously be able to do even cooler things like proper animations, media etc

Have fun, the full source is available on my skydrive

1 comment:

Faisal said...

Great post.I've learnt a lot from this article.