Hanalei, Hawaii 9/2/2010
438 Posts and Counting

Silverlight Day 2: Creating A Data-driven Control

Wednesday, June 06, 2007 -

This is going to be one of those "silly" examples, but I hope it illuminates the Silverlight landscape a little. In this post I'll work up an ASP.NET website, create a Silverlight control, and feed it some data from SQL Server.

Prerequisites
I'm using Silverlight 1.1 Alpha. To play along you'll need to install the goodies from here, which are:

One thing I'd like to point out here is that Orcas is silly fast. It's wonderful to have the IDE back :).

Step 1: Create the Web site
Simple stuff really, we all know how to do this. Open up Orcas and go to File >> New Website. Pick your favorite language - mines C# so I'll choose that.

Step 2: Create a Silverlight project. Same deal here - just go to File/New Project, select your language, and then Silverlight. From this menu choose "Silverlight Application":

create_ag

Step 3: Add in a folder to hold client-side script to your web application. I like to call mine "js" by habit - call yours what you like. In it, add a file called "CreateSilverlight.js", and leave it blank for now.

Step 4: Drag the "Silverlight.js" file into your web app's js folder, and the "Page.xaml" file into the web's root- we're not going to use this project for this example - instead (to illustrate a little more how the players play together) we're going to put the pieces together in one place.

Step 5: Create an aspx web page that doesn't have a code-behind, and no master page. Call it XAMLPage.aspx for now. When finished, your project should look something like this:

project

Step 6: Create some basic XAML for testing. In this example I'm going to create a simple TextBlock that says (what else) "Hello World" and put it into Page.xaml:

<Canvas
        xmlns="http://schemas.microsoft.com/client/2007" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        x:Name="parentCanvas" 
        Width="640"
        Height="480"
        >
  <TextBlock Name="myBlock" 
             Text="Hello World" 
             Width="200" 
             Height="200" 
             FontSize="22" 
             Foreground="#FF000000"/>
</Canvas>

What we want to do here is to call Default.aspx, instance a Silverlight control, and then feed that control some data. To do this, we need to utilize some javascript. The Silverlight.js page is a requirement for running any Silverlight apps on a web page, since it has all the goodies in it to detect the client, detect installation, and instance Silverlight. We don't want to change that file at all since it's does it's job well.

The second js file, which is blank, is a jscript file that will create the client and feed it some XAML (this is optional). Let's take a look at the script needed for this page:

// JScript source code

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

This is all the script that's in the file, and it's only one method. If you want to customize anything about the control - here is the place to do it. Two things to notice here is that we're telling the control to load the source "Page.xaml" (we're going to change that in a bit), and that we're looking for the element "SilverlightControlHost", which doesn't exist yet. So let's change that.

Step 7: Code up the ASP page. So to make sure everything's wired properly, I'm going to load up an ASPX page and call the Silverlight functions, which in turn will load my Page.xaml file into the Silverlight control. So pop this code into your default.aspx page.

<%@ Page Language="C#" AutoEventWireup="true"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script type="text/javascript" src="js/Silverlight.js"></script>
<script type="text/javascript" src="js/CreateSilverlight.js"></script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Hello Silverlight, So Glad To Meet You!</title>
</head>
<body>
    <form id="form1" runat="server">
    </form>
    <div id="SilverlightControlHost" >
        <script type="text/javascript">
            createSilverlight();
        </script>
    </div>
</body>
</html>

So let's take a look at what's going on here. The page is loading up, and is referencing the two script files located in our script directory. We've also setup a DIV with the id "SilverlightControlHost", and then implanted (for readability) a script call to the "createSilverlight()" method. This method, in turn, instances Silverlight in the browser and then sets the control's XAML source to Page.xaml. Simple enough, and here's what you should see when running the page:

firstrun

 

Groovy! Ok everything's working nicely, now let's do something more fun shall we?

Step 8: Make it dynamic. Let's copy the source of our Page.xaml file and put it into an ASPX page - the XAMLPage.aspx that we talked about above. Now that it's in there we can have some fun - like adding some scripting for fun :). Add this source to XAMLPage.aspx:

<%@ Page Language="C#" %>
<Canvas
        xmlns="http://schemas.microsoft.com/client/2007" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        x:Name="parentCanvas" 
        Width="640"
        Height="480"
        >
  <%for (int i = 1; i <= 10; i++)
    { %>
  <TextBlock Name="myBlock<%=i.ToString() %>" 
  Text="Hello World <%=i.ToString() %>" 
  Width="161.013" Height="62.537" Canvas.Left="-1.013" 
  Canvas.Top="<%=20*i %>" FontSize="22" Foreground="#FF000000"/>
  <%} %>
</Canvas>

Not doing much tricky here - just looping 10 times over the TextBlock declaration, and outputting some info. One thing to note is this bit: Canvas.Top="<%=20 * i %>"  this is important since XAML elements will stack, and there is not grid layout or stack panel in Silverlight yet - so you need to be explicit about positioning here. In this case I'm going to stack things 20 pixels apart vertically.

Step 9: Reset the "source". Open up CreateSilverlight.js and reset the source element to "XAMLPage.aspx":

    Sys.Silverlight.createObjectEx({
        source: "XAMLPage.aspx",

When you run this, you should see:

run2

 

OK great - the Hello World thing is out of the way - now let's do something a little more worth while, and let's make the scripting a little more usable.

Step 10: Refactor the scripting. We obviously don't want to hardwire these things into our script files - although that is an option if you want to partition each load up of a Silverlight control into it's own script file. In this case I'd like to have one routine load up every Silverlight control on my page. So I'm going to refactor CreateSilverlight.js to allow me to pass in the source and elementid as variables:

// JScript source code

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

Step 11: Let's do something useful - let's create a menu and a nice welcome message! I created a nice menu control using Expression Blend (more on blend in other writeups) that did you basic jiggety jig when you moused over, and I also created a nice welcome message using some text blocks and the current date. I called the welcome page "XAMLWelcome.aspx" and added this XAML:

<%@ Page Language="C#" %>
<Canvas
        xmlns="http://schemas.microsoft.com/client/2007" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        x:Name="parentCanvas" 
        Width="200"
        Height="35"
        >
  <TextBlock Name="welcomeMessage" 
  Text="Welcome back <%=User.Identity.Name%>"
  Width="161.013" Height="62.537" Canvas.Top="-1" Canvas.Left="-1.013" 
  FontSize="22" Foreground="#FF000000"/>
  <TextBlock Name="theCurrentDate" 
  Text="<%=DateTime.Now.ToLongDateString() %>"
  Width="161.013" Height="62.537" Canvas.Top="25" Canvas.Left="-1.013" 
  FontSize="12" Foreground="#FF000000"/>
</Canvas>

Next, I added in the menu control. To do this, I had to copy over the Menu XAML file (called Menu.xaml) as well as the dll that the was created as part of my project. I did some code behind to respond to client events (mouse overs and so forth) so this created a dll. To know where to put the DLL, let's take a look at the source of the menu xaml (only the top lines):
<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="AGDemo.Menu;assembly=ClientBin/AGDemo.dll"
        Width="640"
        Height="480"
        Background="White"
        >

Notice the "x:Class" declaration - this tells you where Silverlight's going to look for the dll to fire the menu. So in our web project I need to create a "ClientBin" directory, then add the output dll (AGDemo.dll) to the folder.

The good news here is that you can "link" your web projects to a Silverlight project - see Scott's demo to see more of how that works.

OK, now I have my menu control, and I have my new Welcome control worked up. Let's add them to the page:

<%@ Page Language="C#" AutoEventWireup="true"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script type="text/javascript" src="js/Silverlight.js"></script>
<script type="text/javascript" src="js/CreateSilverlight.js"></script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Hello Silverlight, So Glad To Meet You!</title>
</head>
<body onload="loadAG()">
    <form id="form1" runat="server">
    </form>
    <div id="Welcome" style="height:60px">
    </div>    
    <div id="Menu" >
    </div>
   
    
</body>
</html>
<script>
function loadAG(){
    createSilverlight("Menu.xaml","Menu");
    createSilverlight("XAMLWelcome.aspx","Welcome");

}

</script>

Notice here that I renamed a few things - I created a DIV to hold my welcome message, and then a DIV to hold the menu (such as it is). I then use the onload() event of the body tag to call createSilverlight() for each element I want to load.

Here's the result:

run3

 

 You can't really tell very well, but the menu bounces and moves nicely all over the place :). It's still not very useful, but that's the goal for my next post!

Related


Gravatar
DotNetKicks.com - Wednesday, June 06, 2007 - You've been kicked (a good thing) - Trackback from DotNetKicks.com
Gravatar
Mike - Wednesday, June 06, 2007 - I will be reading this every day and really appreciate you taking us with you on your journey!
Gravatar
Member Blogs - Wednesday, June 06, 2007 - .NET The Var Of The Worlds - explanation on Var using LINQ Telerik Product Support Lifecycle: Which versions
Gravatar
Kevin Dente - Wednesday, June 06, 2007 - Tunnels? Do you name all of your machines after Kauai beaches? ;)
Gravatar
Rob Conery - Wednesday, June 06, 2007 - Almost :). My server is COUNTYLINE, my XP box is VELZYLAND, but my laptop is PICKLE (my daughther's idea).
Gravatar
Michael's Blog - Thursday, June 07, 2007 - During the weekend I spent some minutes to collect some of the greatest Silverlight examples. Most of
Gravatar
Remmus - Thursday, June 07, 2007 - I like the look of Silverlight and the surrounding technology but it scares me a little.

I am worried with how easy they are making it to create such rich content that the number of sites only using technology such as this will increase massively.

Why is this is a bad thing you ask? Can visually impaired / blind users use it? If not you are cutting out a number of potential users from using your site. Plus I think you be breaking a number of disability laws and leaving yourself open to a lawsuit.

Not sure this is actually relevent to this post but I would be interesting in hearing where others see the technology 'fits in'
Gravatar
Michael's Blog - Thursday, June 07, 2007 - During the last days I have added some new tutorials and examples to my list. Dave Campbell sent me a
Gravatar
Jonas - Thursday, June 07, 2007 - Thanks for the tutorial. It is very helpful for someone like me, who does not have Silverlight on the primary focus but who does not want to miss the bandwagon either...

But seeing the result, I am shocked:

JavaScript dynamically calling ASPX which embeds XAML which embeds C#? (or is it actually the ASPX that embeds the C#?)

Can this be the all-praised, shiny future?

This seems quite an abnormity to me... I am worried, that if this is going mainstream, the schizophrenia-rate among IT-Professionals will rise significantly.
Gravatar
Rachit - Friday, June 08, 2007 - This style of examples are so much better than the one listed on silverlight.net. Thanks Rob!
Gravatar
Thomas Wagner - Friday, June 08, 2007 - Rob- I am wondering what sort of hardware you are running Orcas on. Is it a laptop or a desktop?
Gravatar
WynApse - Friday, June 08, 2007 - Silverlight Cream for June 8, 2007
Gravatar
Rob Conery - Friday, June 08, 2007 - @Jonas: yes initially I am a little... I dunno "head-scratchy" about it all, but I have to remind myself it's all still alpha - not even beta yet :) so I'm keepin the faith.

@Thomas: I run it on a desktop and it's very very fast.
Gravatar
Rachit - Sunday, June 10, 2007 - Did I miss something here? Step 1, you are creating a C# web site and Step 2, you are creating a Silverlight project. What's the relation between them? Are we mixing these two projects?

Did you miss something?
Gravatar
Rob Conery - Sunday, June 10, 2007 - @Rachit: The relation between them is just like a control lib for a "normal" web site. You don't need to have a Silverlight Project - it just helps for debugging and so on.

If you could be more specific with your questions I'll do my best to help you.
Gravatar
Igor Sul - Monday, June 11, 2007 - Good post !

Download free eBooks from http://sharpbooks.blogspot.com
Gravatar
Dutt - Monday, June 11, 2007 - Your Post is very useful.
Currently I am working with silverlight, and publishing resources and tutorials on silverlight at http:\\www.silverlighttutorials.blogspot.com

This could be useful for silverlight application developers.
Gravatar
Pete w - Monday, June 25, 2007 - Rob,
Are you still in Redmond?
Last week we were debating about whether UDFs were a "Good" way to go for read-only access operations:
http://www.ayende.com/Blog/archive/2007/06/20/Shocking-Rob.aspx

You offered to ask some of the folks on the SQL server team, and it left some of us hanging. I was interested in hearing their take on UDF usage.
Did you ever get any feedback? I'd love to know.
-pete
Gravatar
Bryan Chow - Thursday, July 19, 2007 - ???????silverlight???blogGreatVisualStudioQuickStarts
Gravatar
Chris Bowen's Blog - Monday, July 30, 2007 - Though the jury is still out on what controls we'll see in or alongside Silverlight 1.1 when it's released,
Gravatar
Noticias externas - Monday, July 30, 2007 - Though the jury is still out on what controls we&amp;#39;ll see in or alongside Silverlight 1.1 when it&amp;#39;s
Gravatar
MrRudy - Thursday, August 16, 2007 - I can't add your feed to Feedburner. How I do this?
Gravatar
Thameem - Thursday, May 07, 2009 - Can't see the images, seems it has been moved can you please check out and update it.