Silverlight 4 Project Types part III – Silverlight Class Library

Last time, I looked at the Silverlight Navigation Application choice in Silverlight’s New Project wizard.  Next, I’d like to look at the Silverlight Class Library choice.  This is next on the list, out of the six different project types that are listed in the New Project wizard when you pick Silverlight as a project type.

Creating a Class Library

What exactly is a class library?  Well, simply put, it’s a library containing the implementation of one or more classes, implemented as a .NET DLL.  The basic idea is to move basic functionality that you’d likely use in more than one place out to a common library that one or more applications can use.

Silverlight lets us easily create a class library that we can then deploy with our actual Silverlight application.  The class library would contain code that we could invoke from our Silverlight application.

Let’s create a basic Silverlight Class Library using the New Project wizard.  Here’s what the dialog looks like:

Once you enter your project name and click OK, you see the dialog shown below.  This is where you get to decide which version of Silverlight you’re targeting. We saw something similar when creating a Silverlight Navigation Application.

For this project, we’ll stick with version 4 of Silverlight.  Keep in mind that if you author a Silverlight 4 project, the client will need to download Silverlight 4.  If you’re curious about what specific changes were made between Silverlight 3 and Silverlight 4, you can take a look at the article:  Ensuring that Your Silverlight Applications Work with Silverlight 4.  Note the “quirks” mode, in which the Silverlight 4 runtime can behave like Silverlight 3, to avoid breaking applications that targeted version 3.

Here’s what the solution looks like, after the wizard creates it.  Pretty simple.

The obvious question is: how is this different from a standard class library, that you might use with Win Forms or a WPF application?  If we just create a standard class library and then compare the project that we get with our Silverlight Class Library,we see basically the same thing–an empty DLL containing a single class.

One real difference that you’ll notice is related to which assembly references are included in the project by default.  Take a look at the projects shown below.  On the left is a standard C# class library.  On the right is a Silverlight Class Library.  (Nevermind that I’ve changed the default class from “Class1” to “Cat”.

You’ll see some similarities and some differences.  The main thing to remember is that the Silverlight project is built against the Silverlight versions of all of these libraries, rather than the standard .NET Framework versions.  You can convince yourself that there is more than one set installed one your machine by looking at the directory “C:\Program Files\Reference Assemblies\Microsoft\Framework”.  Make note of the .NET Framework and Silverlight sub-directories, with various version numbers under each sub-directory.  If you drill down into the sub-directories, you’ll see the actual .NET Framework or Silverlight DLLs.  There is a completely different set of DLLs for each platform.  As an example of the differences, note that there is a System.Windows.Forms.dll in the .NET Framework directories, but not in the Silverlight directories.

One other thing to remember is that even when you see the same file in both .NET Framework and Silverlight directories, the content of the file may be different.  For example, the Silverlight version of System.Core doesn’t include the System.Diagnostics namespace, because for Silverlight, it’s implemented in mscorlib instead.

There is another important difference between the different versions of the framework–the Silverlight versions are much smaller than their full .NET Framework counterparts.  Remember that Silverlight needs to be deployed over the web, so its copy of the Framework is considerably smaller than the full .NET Framework.  If you just look on a system that has both and compare total size of the files in each directory, you’ll see:

  • Version 3.0 of the .NET Framework = 84.4MB
  • Version 4.0 of the .NET Framework = 189MB
  • v3.0 of Silverlight framework = 20.6MB
  • v4.0 of Silverlight framework = 24.6MB

So the Silverlight runtime is only about 13% of the size of the full .NET 4.0 Framework.  Pretty amazing.

Adding Some Code

Now let’s add some functionality to our Silverlight class library.  We’ll create a Cat class that we can later use in our Silverlight application.  Here’s the implementation:

public class Cat
{
    public string Name { get; set; }
    public string Motto { get; set; }
    public uint NumLives { get; set; }

    public Cat() { NumLives = 9; }

    public void Die()
    {
        if (NumLives > 0)
            NumLives--;
        else
            throw new Exception("This cat is already dead");

        return;
    }
}

Building the Library

What do we get when we build the library that contains an implementation of our Cat class?  As it turns out, we just get a regular .NET DLL.  Let’s take a look at what shows up in our \bin directory:

Take a look at what’s in this directory.  Using the IL DASM tool (Intermediate Language Disassembler, which can be found in Windows 7 at C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin), crack open the DLL and you’ll see:

We could also look at the manifest for our Silverlight class library and compare it with manifest for a .NET 4.0 version.  If you did this, you’d see that the main difference is the version of mscorlib that they reference.  .NET 4.0 class libraries reference version 4.0.30319 of mscorlib and Silverlight 4 class libraries reference version 2.0.50727.  This could be because of the timing of the Silverlight and .NET 4.0 releases–Silverlight 4 just ended up using the version of mscorlib that shipped with .NET 3.5.  Or maybe it’s the case that Silverlight doesn’t make use of any of the new functionality added to .NET 4.0.

The bottom line here is that both class libraries (.NET 4.0 and Silverlight) are structurally the same–just .NET DLLs.  But they are not interchangeable, because they depend on different versions of various .NET DLLs.

Using Our Class

Now let’s actually use the class that we just created.  We’ll go back to our SilverlightClassLibrary1 solution and add a Silverlight Application project.  We leave the option turned on that automatically generates an ASP.NET Web Application project.

The solution now looks like this:

So we have a web project that loads our Silverlight application and we now want to change the application to make use of our class library.  Specifically, we’ll add some code that makes use of our Cat class.

On the MainPage control in the Silverlight application, we switch to the Events tab in the Properties window and double-click to the right of the Loaded event, to generate an event handler for Loaded.

Next, we add a reference to SilverlightClassLibrary1 in the Silverlight application.  In the Solution Explorer, we right-click the References folder in the SilverlightApplication1 project and select Add Reference.  Then we just click on the Project tab and select SilverlightClassLibrary1.  Now we see the class library show up as a reference in the Silverlight application.

Next, we open MainPage.xaml.cs in the code editor and add a using statement at the top for our class library.   Then we add code to the Loaded event to create a new instance of a Cat.  MainPage.xaml.cs now looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SilverlightClassLibrary1;

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        Cat _garfield;

        public MainPage()
        {
            InitializeComponent();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            _garfield = new Cat();
            _garfield.Name = "Garfield Arbuckle";
            _garfield.Motto = "Carpe Catnip";
        }
    }
}

Now let’s do something with our cat.  We go back to the design surface for the main window, add a new button, change the Content property to “Kill” and then double-click on the button to create an instance of the button’s Click event.  The code for the Click event is pretty simple–we just tell Garfield to die.

private void button1_Click(object sender, RoutedEventArgs e)
{
    _garfield.Die();
}

Now we’ve created a Cat and we have a button that lets us kill the cat (repeatedly).  As a next step, let’s just add a label on the main page that indicates how many lives the cat has left.  After you drag the label onto the design surface, it will look like this:

Let’s think about the best way to display the number of lives.  One way would be to add a line in button1_Click() that resets the label’s Content property every time we invoke the Die method.  But the drawback of this is that if we have other places in our code that cause our cats # lives to decrement (or increment), we’d have to remember to add code to all of those places to also update the label.  Better than manually updating the label would be to just “bind” it to Garfield’s NumLives property.  We’d like the label to change automatically whenever Garfield’s NumLives property changes.

Doing the data binding involves two main steps.  The first is to specify the binding of the label’s Content property.  We can set up the binding in XAML, specifying the binding Path, which indicates which property of the Cat object we want to bind this label to.  Below is the XAML for our main page, showing both the Button and the Label.  Note the value of the label’s Content property, with the binding path specified.

<Grid x:Name="LayoutRoot" Background="White">
    <Button Content="Kill" Height="23" HorizontalAlignment="Left" Margin="153,69,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    <sdk:Label Height="28" HorizontalAlignment="Left" Margin="165,26,0,0" Name="label1" VerticalAlignment="Top" Width="63" Content="{Binding Path=NumLives}" />
</Grid>

(For more info on data binding in Silverlight, see this Silverlight Data Binding article in MSDN).

There’s one more thing that we have to do to get the binding to work.  We need to also specify the object that we’re binding to.  In our case, the object is the instance of the Cat that we created in the Load event–Garfield.  We do this by setting the DataContext property of our main page.  Really, we want to set the DataContext property of the Label.  But we can just set the data context for the whole page and then that data context will automatically get used for all controls on the page (if they don’t set their own data context).  This would be handy if we plan on adding other controls later that are also bound to Garfield.  We do this in our Loaded event:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    _garfield = new Cat();
    _garfield.Name = "Garfield Arbuckle";
    _garfield.Motto = "Carpe Catnip";

    // Set data context of main grid to be our Cat object
    LayoutRoot.DataContext = _garfield;
}

Now let’s try running our application.  When the Silverlight application starts up in a web browser, it looks like this:

Hey, that looks like success.  Our Label appears to have been bound to the NumLives property, because it’s showing that Garfield has 9 lives.

But what happens when we press the Kill button?  When I try it, nothing happens.  Inside the Cat object, the NumLives property should be decrementing.  And our Label should reflect the new value, since we set up the data binding.  But the label doesn’t appear to be changing.  Why not?

As it turns out, the NumLives property is changing internally whenever we kill Garfield.  But our client–the MainPage–is not being told that the property changed.  So the data binding isn’t fully functional and the label does not update.

We missed one small step when we set up data binding on our Cat object.  To properly bind to an object’s property, we need our Cat class to implement the INotifyPropertyChanged interface and to fire the PropertyChanged event whenever the NumLives property changes.  (For more info on INotifyPropertyChanged, see the MSDN documentation for INotifyPropertyChanged Interface).

To start with, we change our Cat class definition to indicate that we plan to implement the INotifyPropertyChanged interface.

public class Cat : INotifyPropertyChanged

If you try to build the project now, you’ll get an error telling you that you haven’t implemented the PropertyChanged event.  This is because when we inherit from INotifyPropertyChanged, we’re agreeing to a contract that says we’ll implement the interface’s methods.  In this case, it means that we’ll implement the PropertyChanged event.

The easiest way to implement the event is to right-click on INotifyPropertyChanged and select “Implement Interface”.  Then select “Implement Interface” again.

When you do that, you’ll get the following event declaration added to your code:

public event PropertyChangedEventHandler PropertyChanged;

Next, we need some code that will fire this event.  So we create a little method that we can use throughout our class.  I added the following code after the event declaration:

public void OnPropertyChanged(PropertyChangedEventArgs e)
{
    if (PropertyChanged != null)
        PropertyChanged(this, e);
}

Finally, we need to fire this event whenever the value of NumLives property changes.  We do this by invoking the OnPropertyChanged method that we just implemented.  We also have to pass the name of the property that is changing when we fire the event.  Here is the updated code for the NumLives property:

private uint _numLives;
public uint NumLives {
    get { return _numLives; }
    set
    {
        _numLives = value;
        OnPropertyChanged(new PropertyChangedEventArgs("NumLives"));
    }
}

That should be everything that we need to get the data binding to work.

For reference, here is the full source code listing for our Cat class:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace SilverlightClassLibrary1
{
    public class Cat : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, e);
        }

        public string Name { get; set; }
        public string Motto { get; set; }

        private uint _numLives;
        public uint NumLives {
            get { return _numLives; }
            set
            {
                _numLives = value;
                OnPropertyChanged(new PropertyChangedEventArgs("NumLives"));
            }
        }

        public Cat() { NumLives = 9; }

        public void Die()
        {
            if (NumLives > 0)
                NumLives--;
            else
                throw new Exception("This cat is already dead");

            return;
        }
    }
}

Killing the Cat

Finally, let’s run our application.  Now when we start up the application and run it in browser, we see the # lives indicator decrement whenever we click the Kill button.  Success!

Deployment

Let’s look at one more thing.  When we create and use a Silverlight class library and then deploy and run our Silverlight application, what is really going on?  We saw earlier that we’re creating a DLL.  But what actually happens to that DLL when some client hits the web page that hosts our Silverlight Application?

In Windows Explorer, let’s find the project directory and drill down until we see the ClientBin directory under the SilverlightApplication1.Web project.

In ClientBin dir, we see just one file: SilverlightApplication1.xap.  This is the XAP file that represents our Silverlight application and which gets deployed by the web server whenever a client loads the hosting ASP.NET page.

Let’s take a look inside the .xap file.  (Just rename the extension to .zip and double-click to open the .zip archive).  Here’s what we see:

The important components to notice are SilverlightApplication1.dll and SilverlightClassLibrary1.dll.  SilverlightApplication1.dll is the main DLL that contains our Silverlight application (MainPage class, derived from Silverlight UserControl).  SilverlightClassLibrary1.dll is the output of our SilverlightClassLibrary1 project–a DLL that contains our Cat object.  So we see that when our Silverlight application is deployed, the referenced class library is also deployed to the client, since it is included in the .xap file.

Finally

Now we’ve seen the main purpose of the Silverlight Class Library.  You can create a separate DLL that contains one or more classes that your Silverlight application is going to make use of, when running on the client.  Since the Silverlight application makes use of the class library, the class library is deployed to the client along with the main Silverlight application.

Silverlight 4 Project Types part II – Silverlight Navigation Application

Last time, I took a look at what gets created when you create a new Silverlight project and choose Silverlight Application as your project type in the New Project wizard.  Now I’d like to look at the Silverlight Navigation Application project type that is new for Silverlight 4.

As usual, I’d like to walk through the process of creating a new project and then take a quick peek at what’s under the covers.  There are a number of pieces here that are complex enough for their own blog post.  So I’ll probably use the phrase “cover this later” a lot.  My goal right not is to just get a high-level view of the Silverlight Navigation Application.

Just a quick note on the tooling: I’m currently still using the Beta 2 build of Visual Studio 2010.  So some of the behavior or layout might be different from the final release.

Below is an image of the New Project dialog in Visual Studio, showing the new Silverlight Navigation Application choice.  This is the type of project that I’ll be creating.

If you pay attention to the text describing each template, displayed over on the right, you’ll see a slight difference between the Silverlight Application and the Silverlight Navigation Application.

  • Silverlight Application – A blank project for creating a rich internet application using Silverlight
  • Silverlight Navigation Application – A project for creating a rich internet application using Silverlight

So with the Silverlight Navigation Application, you get just a bit more of the framework for an actual production Silverlight application.

If we click OK to continue, we get the familiar dialog for creating a sample web project in which to host the Silverlight application.  As before, we can choose between a Web Application, a Web Site, or an MVC Web Site.  I’ll just pick a Web Application project type.

Note the new checkbox on this dialog labeled Enable .NET RIA Services.  RIA Services (now called WCF RIA Services) is an n-tier design pattern in which you have Silverlight on the client, ASP.NET as the middle tier and then some sort of data tier.  More on this later.  For now, you can get an introduction at the WCF RIA Services home page.  I first heard about RIA Services at Microsoft’s PDC 2008 conference and remembering that it sounded very similar in its goals to Rocky Lhotka’s CSLA.NET for Silverlight framework.

Let’s compare the Silverlight Application and Silverlight Navigation Application projects side by side.  Here’s the high-level view.  (The Silverlight Navigation Application is on the right).

The first difference you’ll notice are the Assets and Views folders in the Silverlight Navigation Application.  Taking a quick peek at these folders, you get an idea of what they contain.

The navigation application adds a Resource Dictionary, Styles.xaml, which serves as a sort of stylesheet for the application.  In the Views folder, we get a new control for displaying errors, ErrorWindow.xaml, and a couple pages where we’ll show our actual web site content, About.xaml and Home.xaml.

We’ll find the biggest changes in the MainPage.xaml file and its code-behind.  But before we take a look at the code, let’s just run our application to see what it looks like so far.

Wow.  That’s slick.  Instead of the blank page that we got with the Silverlight Application, it looks like we get a small, but fully functional web site, implemented entirely in Silverlight.

If you move the mouse around a little bit, you’ll discover that you can click on the home and about labels in the upper right corner of the page to navigate between a Home page and an About page.  When the Silverlight application first starts, we get the Home page.  If you click on the about label, you navigate to the About page.

This highlights that there are two fundamentally different ways to use Silverlight:

  • Silverlight controls embedded in ASP.NET web pages
  • Silverlight as the entire application

In the first case, you create individual Silverlight controls for the areas of your web site where you need a richer user experience and embed them in ASP.NET (or plain old HTML) web pages.  You can think of the Silverlight as little islands of interaction embedded in a traditional ASP.NET web site.

The other basic way to use Silverlight, highlight by the Silverlight Navigation Application, is to make Silverlight handle the entire user experience.  Instead of a web page, you have Silverlight running in the browser as a true RIA (Rich Internet Application).

Which is a better way to use Silverlight?  Neither.  You might consider creating your entire web application in Silverlight, to give your users a richer experience.  But doing that also means that you’re hiding your content in a Silverlight black box that search engines might not be able to crack open to get at the content.  It also means that you’re out of luck for users who haven’t downloaded and installed the Silverlight plug-in.

The Main Page

Ok, let’s go back to the XAML for the main page and figure out how this page navigation is working.

If we’re curious about how things get started, we can go back to the project and note that the App object is listed as the startup object for our application.  If we look at its code behind, we see that it sets the main object to be displayed as an instance of MainPage, just like the standard Silverlight Application.

Before we look in any detail at the MainPage object, let’s take a quick look at how it looked for our standard Silverlight Application–the template that Visual Studio calls a “blank” Silverlight project.  Here’s the XAML:

MainPage is just a UserControl that contains a white grid, onto which you can put anything that you like.  This is the tabla rasa for Silverlight controls.

Now let’s take a look at the same XAML, for the MainPage object, in our Silverlight Navigation Application.  We find that it also derives from UserControl and the XAML consists of a UserControl tag, which contains a Grid.  But this time, the grid is far from empty.

There’s a lot of junk in the XAML for the MainPage control.  But if we strip it down to the main elements, we get the following basic outline (starting with the outer Grid, which is contained in the UserControl):

<pre><Grid Name="LayoutRoot">
    <Border Name="ContentBorder">
        <navigation:Frame Name="ContentFrame">
    </Border>
    <Grid Name="NavigationGrid">
        <Border Name="BrandingBorder">
            <StackPanel Name="BrandingStackPanel"/>
        </Border>
        <Border Name="LinksBorder">
            <StackPanel Name="LinksStackpanel"/>
        </Border>
    </Grid>
</Grid>

This looks a bit busy, but it’s pretty straightforward.  The two main objects in the XAML match the two main areas of the screen that we saw when we ran our Silverlight application–a navigation area at the top of the window that contains the “home” and “about” navigation buttons and then our main content area.  This content area is a container (a Frame object) that will contain our actual content (individual Page objects).

In this XAML fragment, ContentFrame is the container where we put all of our main web page content.  It’s contained, in turn, in a Border object that will add some basic formatting to the frame.

The NavigationGrid object, which contains the navigation buttons, is a little less interesting.  So let’s look first at the ContentBorder and the ContentFrame.

Here’s the full XAML fragment for these guys:

<Border x:Name="ContentBorder" Style="{StaticResource ContentBorderStyle}">
    <navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"
                      Source="/Home" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">
        <navigation:Frame.UriMapper>
            <uriMapper:UriMapper>
                <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
                <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
            </uriMapper:UriMapper>
        </navigation:Frame.UriMapper>
     </navigation:Frame>
</Border>

The ContentBorder is just a wrapper around the ContentFrame that adds:

  • A margin at the top of the page, making room for the navigation controls
  • A gradient brush for the frame’s background

You can see the details by opening the Styles.xaml file and looking at the ContentBorderStyle style.

The Navigation Frame

The frame object (System.Windows.Controls.Frame) is where all of the magic happens.  MSDN says that this control is a “content control that supports navigation”.

The basic idea of a Frame is that you can tell it the URI of the content that you want to have it display.  You normally do this by setting its Source property or by calling its Navigate method.

When our application first starts up, the Source property of the ContentFrame gets set to “/Home”, since it’s set in the XAML.  This causes the /Views/Home.xaml page to get loaded by default.

But we also load content into the frame when we click on the home and about buttons in the navigation grid at the top of the screen.  These two buttons are actually HyperlinkButton objects.  Here’s the XAML for our about button (you can find this in MainPage.xaml):

<HyperlinkButton x:Name="Link2" Style="{StaticResource LinkStyle}"
                 NavigateUri="/About" TargetName="ContentFrame" Content="about"/>

The HyperlinkButton lets us navigate to a new web page by specifying a URI and the target control where that URI should get loaded.  In our case, we tell it to load “/About” as the URI in our ContentFrame.  This will have the same effect as if we’d set the Source property of the ContentFrame to “/About”.

So we change the content in the ContentFrame object at three different points:

  • At startup, we navigate to Home.xaml
  • When user clicks on the about button, we navigate to /Views/About.xaml
  • When user clicks on the home button, we navigate to /Views/Home.xaml

URI Mapping

But how is it that we specified “/About” as a URI and we end up at the page /Views/About.xaml”?  When we just specify “/About”, how does the Frame get the exact URI that describes how to find the actual .xaml file?

This happens through something called URI Mapping.  URI mapping simply means that you can map one URI to another, using a simple lookup table.  In general, this is used to map longer URIs to shorter, or internal, URIs.  In our case, when we pass the URI “/About” to our Frame, it uses its UriMapper object to map this URI to “/Views/About.xaml”–the true path to the page that we want to load.

You can see the rule that does this mapping in the XAML fragment above that contains the ContentFrame and XAML elements that specify the UriMapper property of the Frame.  We basically have two rules:

  • Map an empty URI to “/Views/Home.xaml”  (the default/home page)
  • Map “/something” to “/Views/something.xaml”

The second rule is the interesting one.  In the individual UriMapping objects, we can do some basic pattern matching, using one or more variables, denoted by braces.  So the rule lets a user enter just a page name and our mapping fills in the rest.  The mapping rule looks like this:

    <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/></pre>

The whole point here, when we’re talking about user-entered URIs, is that we can hide the details of the URI path from the user and give them something easier to remember and easier to enter.

In the Silverlight Navigation Application example, users aren’t directly entering URIs.  But it still helps to simplify the URIs that we need to specify when setting up the HyperlinkButton objects.

By the way, it’s interesting to note that the Frame class in the main .NET Framework does not support URI mapping, while the Frame class in the Silverlight version of the framework does.

More Fun With Frames

One other very interesting thing about the Frame control is that not only can you tell it to navigate to various pages, but that it remembers its navigation history.  We could then tap into that history and tell the Frame to navigate forward or backward through its history.  For example, I could add a couple of buttons, label them Forward and Back and then add the following code behind.

    private void btnBack_Click(object sender, RoutedEventArgs e)
    {
        if (ContentFrame.CanGoBack)
            ContentFrame.GoBack();
    }

    private void btnForward_Click(object sender, RoutedEventArgs e)
    {
        if (ContentFrame.CanGoForward)
            ContentFrame.GoForward();
    }

We check the CanGoBack and CanGoForward properties before navigating, because if you try to navigate past either the beginning or end of the history, Silverlight will throw an exception.

Even better, the Frame’s navigation history is automatically integrated to the web browser’s history itself (the journal), using the JournalOwnership property.

You can prove this to yourself by running the application generated by the wizard, clicking on the home and about buttons several times and then using the browser’s Back button to see that you can navigate through the pages that you’ve just visited.

This is actually pretty important.  One of the drawbacks of implementing a Rich Internet Application in a black-box technology like Flash is that if you’re navigating between pages, the user loses the ability to use the browser’s navigation buttons to move back/forward through these pages.  Using a Silverlight Frame control addresses this because it ties directly in with the browser’s navigation history.

Wrapping Up

That’s about it for the Silverlight Navigation Application.  The one remaining thing that you can look at is the ContentFrame_Navigated code, in MainPage.xaml.cs. This function is responsible for changing the visual look of the navigation buttons after you click on one of them, to show which content is currently being shown.

The other thing that’s worth doing is opening one of the pages from this project in Expression Blend(As of May, 2010, there is currently a Release Candidate of Blend 4 out that includes support for Silverlight 4).

The easiest way to pop over to Blend from Visual Studio is to just right-click on one of the pages and selected the Open in Expression Blend menu option.

You just click on this option and Blend 4 fires up, opens your project, and then opens the same page in Blend.  Wow.

It’s a good idea to get into the habit of being just as comfortable editing your pages in Blend as you are in Visual Studio.  And that little shortcut in the context menu helps with that quite a bit.

That’s all for now.  Next time I’ll take a look at the next Silverlight project type–the Silverlight Class Library.

Silverlight 4 Project Types part I – Silverlight Application

Ok, let’s take a look at the different types of Silverlight applications that you can create out-of-the-box with Visual Studio 2010.  Now that I’ve installed Visual Studio 2010 and Silverlight 4, I want to take a quick spin through each of the different project types that the New Project wizard makes available.

After firing up Visual Studio 2010, I click on the New Project link and then select the Silverlight project type under C#.  Here’s the default list that I see:

  • Silverlight Application
  • Silverlight Navigation Application
  • Silverlight Class Library
  • Silverlight Business Application
  • WCF RIA Services Class Library
  • Silverlight Unit Test Application

I’d like to take a quick look at each project type, looking at the pieces that make up the project and then thinking a little bit about when to use that particular project type.  As I walk through the various project types, I’d also like to think a little bit about the ecosystem in which the Silverlight application lives.  In other words, what other components might you typically create when designing a solution of that type?

I also want to think a little bit about the tooling.  What tools would you typically use to work on the project that you’re creating?  Would Visual Studio 2010 alone be sufficient?  Or would you spend a lot of time working in Blend?  What about SQL Server 2008?

The Silverlight Application

The first project type—the Silverlight Application—looks like it might be the same thing that I created with Visual Studio 2008 and Silverlight 2, back in the Hello Silverlight World, Part 1 post.

The New Application dialog that we see next is very similar to what I saw with Visual Studio 2008 and Silverlight 2.  As before, we have to host our Silverlight application somewhere.

Notice that this time we have one additional project type that we didn’t have before—an ASP.NET MVC Web Project.  So we can basically go with a “classic” ASP.NET web site or an MVC web site.

The default is to host Silverlight in a new ASP.NET web application project.  But if I uncheck the first checkbox, I get a simple Silverlight project with no containing web site:

If you go this route and then press F5 to “run” your Silverlight application, Visual Studio will just create a test .html page in which to host your Silverlight control.

If you take a look at this page, you’ll see a simple HTML page with a familiar <object> tag hosting the Silverlight control.  (See my post on the Lifecycle of a Silverlight Control for more details on how this is done).

If we instead go with the defaults on the New Silverlight Application dialog (host the Silverlight Application in a new ASP.NET Web Application project), we end up with a simple ASP.NET project that contains both .html and .aspx pages hosting the new Silverlight control.

In either case, .html or .aspx, your Silverlight application is embedded in the web page

<div id="silverlightControlHost">
 <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
 <param name="source" value="ClientBin/SLApp1.xap"/>
 <param name="onError" value="onSilverlightError" />
 <param name="background" value="white" />
 <param name="minRuntimeVersion" value="4.0.41108.0" />
 <param name="autoUpgrade" value="true" />
 <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.41108.0" style="text-decoration:none">
 <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
 </a>
 </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>

As I describedin The Lifecycle of a Silverlight Control, this <div> tag embeds your Silverlight application (control) into a web page using the application/x-silverlight-2 MIME type.  This MIME type now maps to the AgControl.AgControl.4.0 class, implemented in npctrl.dll, which can be found in C:\Program Files\Microsoft Silverlight\4.0.41108.0.

Visually, the pieces of the puzzle look like this (from MSDN article on Silverlight 4.0 Application Services):

So as before, a Silverlight application is managed code that runs in the context of a browser plugin.  Here’s how things work when your browser renders a page containing a Silverlight control:

  • Browser renders HTML  from .html page (or generated HTML from ASP.NET page)
  • Browser sees <object> tag for application/x-silverlight-2 MIME type and fires up the Silverlight plug-in
  • Silverlight plug-in loads the Silverlight core services
  • Silverlight plug-in loads the Silverlight CLR, which creates an AppDomain for your application
  • .xap file containing your Silverlight application is downloaded from the server
  • Your application manifest is loaded/read (from AppManifest.xaml, in .xap)
  • Your main Silverlight application DLL is loaded (from .xap)
  • Silverlight CLR instantiates your Application object and fires its Startup event
  • Your application’s Startup event creates a new instance of your main page (a Silverlight UserControl)
  • Your main page (e.g. MainPage in wizard-generated project) renders itself by reading/loading its .xaml file

Voila.  At the end of all this, you get a Silverlight Application rendered in an ASP.NET web page.  In our case, having generated everything using the Project Wizard, we can just press F5 to run the application–launching a browser window and loading your auto-generated ASP.NET page.  It looks like this (the Silverlight application has the green background):

The XAP Payload

One final topic to cover quickly is–what exactly does the downloaded .xap file contain?  In our wizard-generated test project, you’ll find a ClientBin directory, which contains the compiled Silverlight application in a .xap file.  In our case, it’s named SLApp1.xap.

If you just rename the .xap file as SLApp1.zip and double-click on it, you can see what it contains:

The main pieces here are the application manifest, which tells the Silverlight runtime what object to start up first, and the assembly in which that object lives.  The .xap file also contains the assembly (SLApp1.dll) that contains our actual code.

The .xap file also contains some dependent DLLs, which are sent down to the client as part of the .xap package.

Wrapping Up

That’s all there is to a basic Silverlight Application.  Next time, I’ll take a look at the Silverlight Navigation Application, which lets us create a complete Silverlight application with multiple pages, rather than a single user control.

Creating a Silverlight 4 Development Machine

Now that a Silverlight 4 beta is available, it’s time for me to create a new VM where I can develop Silverlight 4 applications.  This development machine will be based on Windows 7 and include:

  • Visual Studio 2010 Beta 2
  • .NET Framework 4 Beta 2
  • Silverlight 4 Beta
  • Expression Blend for .NET 4 Preview

As of January, 2010, this represents the most complete development environment possible for Silverlight 4 applications.

Operating System

I’ll be installing into a virtual machine environment, using VMware Workstation 6.5.1, running on top of Windows 7 (the host operating system).  The guest operating system, where I’ll be installing the development tools, will be Windows 7 Ultimate.

Both my host and guest machines are 32-bit (x86).

Here’s our “clean slate”–a fresh install of Windows 7 Ultimate with nothing else yet installed:

Fresh Install of Windows 7

It’s a beautiful sight.

Overview

Here’s a complete list of what I’ll be installing in the Windows 7 virtual machine:

  1. Visual Studio 2010 Ultimate Beta 2 (x86)    (19 Oct 2009)
  2. Silverlight 4 Beta Tools for Visual Studio 2010    (2 Dec 2009)
  3. Microsoft for Expression Blend for .NET 4 Preview    (16 Nov 2009)
  4. Silverlight Toolkit    (18 Nov 2009)
  5. WCF RIA Services for Visual Studio 2010 Beta 2    (3 Dec 2009)

I’ll include a link to the location of each tool in the sections below.

Install Visual Studio 2010

I got my copy of Visual Studio 2010 through my MSDN subscription, but you can get a free copy (“Go Live” license) here:

Download Visual Studio 2010 Beta 2

I haven’t tried downloading Visual Studio 2010 from this location, so I’m not sure what edition you get.  But even if it’s one of the Express editions, it ought to be fine for developing Silverlight 4 applications.

We start by launching the VS 2010 installation.

Visual Studio 2010 Installation

The installation begins.

Loading Components

We agree to the license, after carefully reading it.

License Agreement

Next, we choose either a Full or Custom installation.  I always go with Custom, so that I can turn off stuff that I don’t want.  Notice that the default installation takes up 6.4 GB.

Custom Installation

The next screen lets me select individual components to install.  It looks like everything is selected by default.

Select Features to Install

Here are my preferred choices.  I have no interest in VB, VC++ or F#.  For now, I’ll just stick with C#.  I do include the Office Development tools, but don’t need the Dotfuscator feature or SharePoint development tools.  I also uncheck SQL Server 2008 Express, since I’ll later install a full version of SQL Server 2008 when I need it.  This brings the install footprint down to 3.6 GB.

My Selected=

The installation process now starts.  It will take a while, since we have a lot of different components to install.

Installation Begins

A reboot is required after installation of the .NET Framework.

Reboot Required

By the way, it’s interesting to note that version 4 of the .NET Framework actually updates the core components of the .NET Framework.  This was not true of version 3.0 or 3.5, which were both just releases that added to existing functionality.  So 4.0 represents the first time that core libraries have been updated since the 2.0 release in Nov, 2005–just over four years ago.

New Core Libraries

Nearly done now..

Installation Nearly Complete

And the installation is now complete.

Installation Complete

Install Silverlight 4 Beta Tools for Visual Studio 2010

Visual Studio 2010 includes support for Silverlight 3, rather than Silverlight 4.  Because Visual Studio 2010 ships a bit earlier than Silverlight 4 (Visual Studio 2010 shipping in March, 2010 and Silverlight 4 shipping sometime in the first half of 2010), Visual Studio 2010 will support Silverlight 3 rather than Silverlight 4.

You can download the Silverlight 4 Tools for Visual Studio from the link below.  Note that this version of the Silverlight 4 tools works only with Beta 2–not Beta 1.

Download Silverlight 4 Beta Tools for Visual Studio 2010 Beta 2

The install starts:

Silverlight 4 Tools Install

There’s another license agreement to read and accept.

License Agreement

The install begins.

Install Begins

And we’re done..

Install Expression Blend Preview for .NET 4

There is a free preview download of Expression Blend that supports targeting both Silverlight 4 Beta and .NET 4 Beta 2.  It is listed as being compatible with Visual Studio 2010 Beta 2 and can be found at:

Download Expression Blend Preview for .NET 4

This is version 3.1.11111.0 of Expression Blend.  It supports creation of both Silverlight 4 Beta and .NET 4 Beta 2 content, but does not support creation of Silverlight 3 or .NET 3.5 content.  It also does not include SketchFlow.

Note: If you are installing the tools to a virtual machine running in VMware Workstation, you may need to make a change in your display settings for the virtual machine before launching the Expression Blend install.  If the 3D graphics setting is enabled for the VM, the Blend install program may not display properly.  Under VMware Workstation 6.5.1, I’ve seen this problem consistently.  The fix is to disabled the 3D graphics setting for the VM.

3D Graphics Setting

One you disable 3D graphics, the first dialog in the install program will display properly.

Blend Install Starts

The Blend install dialogs are certainly beautiful.

Blend Install

The installation starts:

Installation in Progress

And the installation finishes quite politely.

Thank You

Install Silverlight Toolkit

Next, we install the Silverlight Toolkit, which includes a number of additional Silverlight Controls.  You can find the toolkit on CodePlex.

Download Silverlight Toolkit

The install says that this is the toolkit for Silverlight 3, but the Nov, 2009 release has been updated to include support for Silverlight 4.

Toolkit Install Starts

Yet another license agreement.

Toolkit License Agreement

You next get a chance to decide which components of the toolkit to install.

Silverlight Toolkit Features

Ready to start the install now.

Ready to Install

The Silverlight Toolkit install in action:

Install in Progress

And we’re done.

Install Finishes

Install WCF RIA Services

Next, we install the WCF RIA services, which is a framework that allows writing n-tier ASP.NET/Silverlight applications.

You can find the WCF RIA Services install at:

Install WCF RIA Services for Visual Studio 2010 Beta 2

The link above allows you to download and install the WCF RIA Services.  However, I noticed that when I got to this point, it was already installed.  As it turns out, the install for the Silverlight 4 Beta also installed the WCF RIA Services preview.

Documentation

We’ve now downloaded everything that we need for creating Silverlight 4 applications.  One remaining piece of information that will be helpful is that the Silverlight 4 documentation can be found online at:

Silverlight 4 Documentation

Wrapping Up

There we go.  I now have a clean virtual machine that has everything on it that is needed for creating Silverlight 4 applications.  My one last remaining task is to go and save a snapshot of the VM, so that I preserve the “clean” Silverlight 4 development environment.

Silverlight Gets Full-Fledged Designer Support in Visual Studio 2010

Trying to wrap my head around the current situation with Silverlight 2 and 3 support in Visual Studio 2008 and 2010, I’m confused enough that I feel like shouting out a line from my daughter’s favorite Dr. Suess book, Fox in Socks:  “Now wait a minute, Mr. Socks Fox”!!

It is a little confusing.  But I think I now understand who supports what and I’ll take a stab at jotting it down, for future reference.

Visual Studio 2008 SP1

Visual Studio 2010

  • Supports both Silverlight 2 and Silverlight 3
  • Can install both on the same development machine
  • Each Silverlight project targets one of the two Silverlight versions
  • Silverlight 2 — need to install the Silverlight 2 SDK manually
  • Silverlight 3 — install manually

Ok, as far as I can tell, that’s the current situation.

This basically boils down to two questions:

  • Do I want to develop in Silverlight 2 or Silverlight 3?
    • Silverlight 2 is more stable and is officially released
    • Silverlight 3 (beta) — new controls, navigation framework, out-of-browser support
  • Which version of Visual Studio do I want to use?
    • VS 2008 — easier install experience, stable/released
    • VS 2010 — improved tooling for Silverlight & WPF

The last point is what I want to talk about.  Notice that improved tooling for Silverlight is a feature of Visual Studio, not of Silverlight itself.  Visual Studio 2010 finally gives us full design-time drag-and-drop support for Silverlight.

Let’s see what this looks like.  But first, let’s go back and take a look at the Silverlight design-time experience in Visual Studio 2008.  (I’m using Silverlight 3 here).

The Bad Old Days – Visual Studio 2008 SP1

Until now, Silverlight developers haven’t had the most basic tooling enjoyed by even the lowliest VB6 developers.  Namely — the ability to drag and drop controls onto a design surface and set their properties right in the designer.

Specifically, here’s what you couldn’t do.  If you look at the split window for Silverlight controls in the designer, you’ll notice that the upper pane is labeled “Preview”.

Preview Pane

This was a “Preview” pane because all it could do was to render your XAML on the screen as a preview of how it would eventually look in your Silverlight application.  You couldn’t drag controls onto this surface.  You also couldn’t select any controls in order to reposition them or to set their properties.

In Visual Studio 2008, if you try dragging Silverlight controls onto this Preview window, you just get a big fat “don’t do this” icon.  Even sadder, you can’t select any controls.  If you look at the properties window in Visual Studio, you just see the following sad message:

No Property Editing

Thankfully, you could at least drag and drop controls down into your XAML.  This would at least insert the proper XAML tags for the control that you’d selected.  But you just got an empty tag.  (In the picture below, I’ve just dragged a Button into my XAML).

Drag Into XAML

And, although we weren’t able to set property values in the property editor, there was some consolation in that Intellisense worked in the XAML code.

Intellisense in XAML

So the Silverlight development environment was workable, but not ideal.  Also, you could always author/edit your UIs in Expression Blend.  But then there was a big learning curve to tackle.

Enter Visual Studio 2010

In Visual Studio 2010, we finally have full designer support for Silverlight applications.  In the picture below, I’ve just dragged a Button from the toolbox onto the design surface.

Silverlight Design Surface

It makes me want to weep.  (Who would have thought that a developer would be so happy with being able to drag a button onto a form)?

Not only did the designer let me drag the button onto a design surface, but now it actually gives me a little more than an empty/default Button tag in my XAML.  I actually get a sensibly configured button object, with a reasonable size and a preset label.  Also notice that the upper pane is now labeled “Design”, rather than “Preview”.

But don’t weep yet.  It gets better.  You can actually left-click to select the button in the designer.  When you do this, you’ll see that you can now actually set properties for the button in the property window.

Property Window

Now you may weep or cheer, depending on your particular emotional reaction.

You’ll also notice that you can now click on the little event icon and then double-click to generate event handlers in your code-behind.  (As opposed to using Intellisense in the XAML to discover relevant events).

Event Properties

This is great, although I still don’t understand why there is no dropdown in the properties window to select the individual controls.  Is there a good reason why neither WPF or Silverlight applications allow selecting individual controls from the property window?

Also note that all of the above is possible in both Silverlight 2 and Silverlight 3.

Where Are We?

So clearly, Silverlight is now a full-fledged citizen in Visual Studio, with full tooling.  This may not seem like much, but for anyone who works with Silverlight a lot, it will make a huge difference.  Not to mention a much shallower learning curve for developers coming up to speed with Silverlight.

Mr. Socks Fox wasn’t spouting blibber blubber after all.

Installing Silverlight 3 with Visual Studio 2010 – Step by Step

[Note, 21-May-2010.  Silverlight 4 has been released.  For a step-by-step guide to installing Silverlight 4 with Visual Studio 2010, see my post Creating a Silverlight 4 Development Machine].

A beta version of Silverlight 3 was released at MIX09 in March.  Since a beta version of Visual Studio 2010 was also just released–in May–it makes sense to set up a Silverlight 3 and Visual Studio 2010 development environment.  My last post included screenshots of the installation process for Visual Studio 2010.  This post will cover installing the remaining bits needed for a Silverlight 3 development environment.

Note: Also take a look at the official Getting Started page for Silverlight 3.

This post will describe installing Silverlight 3 bits on top of a clean Windows 7 / Visual Studio 2010 environment.  I won’t install the Silverlight 2 components, so the resulting environment will be targeted exclusively at Silverlight 3.

At the moment, the Silverlight 3 beta is targeted at Visual Studio 2008 SP1, rather than Visual Studio 2010.  (See Tim Heuer’s blog post explaining this).  What this means is that we can’t just run the Silverlight 3 Tools installer.  If you try, you’ll get the following error.

Can't Install on VS 2010

Installing the Silverlight 3 Beta SDK

Instead, you’ll need to just install the Silverlight 3 Beta SDK manually.  Once you download the SDK installer and launch it, you’ll get the following screen:

SDK Welcome

Then you get a license dialog.  Note the comment about this beta license expiring 30 days after the commercial release of Silverlight 3, but no later than 30 Sep, 2009.  Does this imply that we’ll see a final release of Silverlight 3 by 30 Aug, 2009?

License Dialog

If you do a custom install, you’ll see the following features and components listed:

Custom Install

Here’s a quick summary of what is being installed:

  • Silverlight Tools – Components needed for building Silverlight applications
    • The core Silverlight DLLs, e.g. agcore.dll, coreclr.dll, et al
  • Build Components – Components used to build Silverlight projects
    • Microsoft.Silverlight.Build.Tasks.dll,  et al
  • Client Libraries – Silverlight Client Libraries and Controls
    • System.Xml.Serialization.dll, System.Xml.Linq.dll, System.Windows.Controls.Navigation, et al
  • Server Libraries – Silverlight Server Libraries and Controls
    • System.Web.Silverlight.dll, et al

Now we’re ready to install:

Ready to Install

Install continues:

Installing

The install completes, and a dialog reminds us that the actual Silverlight 3 Beta runtime is not yet present.  (Actually, there is an error in this dialog — it’s reminding us that the Silverlight 2 runtime is not present).

SDK Done

Installing the Silverlight 3 Developer Runtime

Now we need to install the actual Silverlight 3 runtime, which you can download from here.

We start with the familiar Silverlight install splash screen (now branded as Silverlight 3 for Developers).

For Devs

Off we go..

Installing Runtime

The runtime install completes quickly.

Runtime Installed

Pretty simple.  You now have all of the important stuff that you need for developing Silverlight 3 applications with Visual Studio.

Building a Silverlight Application with Visual Studio 2010

When you bring up the New Project wizard in Visual Studio, you’ll see two types of Silverlight projects listed:

  • Silverlight Application
  • Silverlight Class Library

New Project

If you create a new Silverlight Application, you’ll see the Add Silverlight Application dialog.  But notice that there is now a dropdown labeled Silverlight Version.  This defaults to Silverlight 2.0, but you can select Silverlight v3.0 to create a Silverlight 3 application.

Create Silverlight 3 Application

You’ll see a similar dialog if you try to create a Silverlight Class Library.

Create Silverlight Class Library

The Silverlight Navigation Application

But notice that there is one Visual Studio template that shows up if you install Silverlight 3 Beta in Visual Studio 2008 SP1 that does not show up in Visual Studio 2010 — the Silverlight Navigation Application.  This is installed as part of the Silverlight 3 Tools installer, which we were unable to run.

We need to pull this particular template from Visual Studio 2008 SP1 into Visual Studio 2010.  To do this, install the Silverlight 3 Tools installer on a machine that is running Visual Studio 2008 SP1.  Then fire up Visual Studio 2008, create a Silverlight Navigation Application project, and select Export Template from the File menu.

Export Template

You’ll see a dialog asking you to select the project to export a template for.  We’ll select the main navigation application.

Export Template

You can also give the new template a description and select an icon.

Template Part II

When you’re done, a new Windows Explorer window will pop up, containing a .zip file for your new template.  Now copy this .zip file to the following directory on your Visual Studio 2010 machine:

C:\Users\myname\Documents\Visual Studio 10\Templates\ProjectTemplates\Visual C#

Now when you bring up the New Project wizard in Visual Studio 2010, you’ll see a new template that you can use to create a Silverlight Navigation Application.

New Template in Action

Wrapping Up

That should do it — you now have a fully functional Silverlight 3 / Visual Studio 2010 environment.

Technorati tags: Silverlight, Silverlight 3, Visual Studio 2010

Hello Silverlight World, part 3 – The Lifecycle of a Silverlight Control

Ok, continuing with building a simple Wizard-generated Silverlight application and then staring at it to see how it works..  Last time, I talked about the Application object in Silverlight vs. WPF.  This time I’ll continue looking at the pieces in the sample Silverlight application, looking at the Page class that was generated and what happens to this control at runtime on a client machine.

Pages vs. Windows

I pointed out a couple of posts back the interesting difference here, just in the terminology.  In Silverlight, your main design surface is a “page”, which sort of comes from the fact that you’re serving up a series of web “pages” with some content in each.  (Nevermind that a Silverlight control can never be an entire page by itself, but must be hosted in an .html or .aspx page).  In WPF, the main design surface is a “window”, which seems appropriate because it runs in a bordered window.

Silverlight’s UserControl Class

In Silverlight, you render all of your content in a class that derives from System.Windows.Controls.UserControl.  When you use the wizard to generate a Silverlight application, it creates a class named Page, e.g.:

    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
        }
    }

One other quick thing to look at, is what else we’re doing in our child class at runtime, beyond what we get in the UserControl base class.  If you build your Silverlight application and then look at the other half of the partial class, i.e. the generated code in Page.g.cs, you’ll see:

    public partial class Page : System.Windows.Controls.UserControl {

        internal System.Windows.Controls.Grid LayoutRoot;

        private bool _contentLoaded;

        /// <summary>
        /// InitializeComponent
        /// </summary>
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public void InitializeComponent() {
            if (_contentLoaded) {
                return;
            }
            _contentLoaded = true;
            System.Windows.Application.LoadComponent(this, new System.Uri("/SilverlightApplication2;component/Page.xaml", System.UriKind.Relative));
            this.LayoutRoot = ((System.Windows.Controls.Grid)(this.FindName("LayoutRoot")));
        }
    }

So, like our App class that derived from System.Windows.Application, the Page class defines an InitializeComponent method that just calls the static Application.LoadComponent method, which just constitutes an object in question, based on its .xaml.  So for both our App and our Page class, the class is getting instantiated and then InitializeComponent causes it to finish initializing by reading the associated .xaml file and then setting properties and creating child objects based on what is in the .xaml.  This is the magic fairy dust that allows .xaml to work–at runtime, the .xaml is just interpreted and associated objects are created.

The second half of this process is happening at the point where we are setting the LayoutRoot property.  The wizard generated some .xaml for our page that has a Grid as the topmost element, with the name “LayoutRoot”.  Then, at code generation time, we get a Grid object declared and then point it to the object that we loaded from the .xaml.  (Using the FindName method).

Where Are We?

Ok, so we’ve seen that there really isn’t much to our Page class, other than the fact that it constitutes itself from the .xaml.  But what is really going on at runtime, on the client where this control will be hosted?

The Lifecycle of a Silverlight Control

To answer that, let’s just walk through the entire lifecycle of our Silverlight control, starting from how the code is downloaded from the server and continuing on to how the Silverlight runtime on the client’s machine loads and renders the control.

It All Starts With a Web Page

plugin-model

Here’s a diagram from the MSDN documentation that gives us the big picture.  Your Silverlight control runs in a managed environment (the Silverlight Common Language Runtime), which in turn runs in the context of a browser plug-in.  And that plug-in runs in the context of a web page that is downloaded from a web server to the client machine.

Remember that when we created our Silverlight application using the Visual Studio wizard, it also generated an ASP.NET web application in which to host our control.  (e.g. SilverlightApplication1.Web).  If you look at the web application, you’ll see that we’ve been given a couple examples of pages hosting our Silverlight control.  Specifically, you’ll see an .aspx and an .html page.  For now, let’s look at the more basic of the two–the .html page.

If you open this test page, e.g. SilverlightApplication1TestPage.html, and scroll to the bottom, you’ll see an <object> tag that mentions Silverlight:

    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"><param name="source" value="ClientBin/SilverlightApplication1.xap"/><param name="onerror" value="onSilverlightError" /><param name="background" value="white" /><param name="minRuntimeVersion" value="2.0.31005.0" /><param name="autoUpgrade" value="true" /><a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
            <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
        </a>
    </object>

What we see here is a standard HTML <object> tag, which allows us to embed a 3rd party plug-in into the browser on the client’s machine.  When rendering the web page, the browser will set aside an area of the page and let the plug-in render directly to that area.  In this case, the 3rd party is Microsoft and the plug-in is Silverlight.

So here’s how things get rolling with our Silverlight control, on the client’s machine (whoever is pointing their browser at your .html page):

  • Client starts up their browser and points it at SilverlightApplication1TestPage.html (let’s assume that the test page is on a web server somewhere)
  • The .html page is downloaded from the web server to the client and the browser begins rendering the HTML content
  • The browser reaches the <object> tag, which indicates that a plugin should be loaded, started up, and allowed to render that part of the page
  • To figure out how to call the plugin, the browser uses the value of the type attribute on the object tag.
  • In our cases, this type is application/x-silverlight-2.  This is a MIME type, which maps to Silverlight 2
  • Using the MIME type, the browser loads the plugin
    • Under Windows, there is a registry entry that associates this MIME type with an ActiveX control named AgControl.AgControl, which in turn is implemented by a DLL npctrl.dll, located in C:\Program Files\Microsoft Silverlight\2.0.40115.0
    • So npctrl.dll is the actual plugin implementation–an unmanaged Windows DLL that implements the plugin API and, in turn, launches the Silverlight CLR–the execution environment in which your Silverlight control actually runs

Ok, if you were paying attention, you may have noticed something surprising in that last bullet point:  ActiveX??  Isn’t ActiveX dead and buried, now that we’re dealing with a managed environment?

Well, yes and no.  The code that we are authoring–our Silverlight control–does run in a managed environment on the client machine, in that it runs inside of the Silverlight CLR/runtime.  But the Silverlight plugin itself has to interact with the web browser and, as such, is unmanaged code that implements that standard browser plug-in API(s) that allow it to run within the browser.

So clearly, npctrl.dll is unmanaged code.  But ActiveX?  The MSDN documentation is not 100% clear on this point, but here’s what I think is going on.  npctrl.dll is both a classic Win32 DLL (non-COM), as well as an ActiveX control (COM server).  Which mode it runs in depends on the browser.   When running inside of Internet Explorer, the plug-in runs as an ActiveX control, implementing the IXcpControl COM interface.  However, when Silverlight is hosted in other browsers, like Mozilla, it implements the Netscape Plug-in API, running as a classic Win32 DLL.  (It implements functions like NP_Initialize and NP_GetEntryPoints).  [This paragraph is mostly conjecture].

Silverlight Presentation Core

silverlight-architecture

Within the Silverlight plug-in, the next layer to take control is the Silverlight Presentation Core.  You can see the Presentation Core as the bottom blue box in this diagram (also found in MSDN documentation).

The Presentation Core is responsible for rendering everything in the browser, handling user interaction, playing video, and parsing XAML.  It’s implemented in agcore.dll, which is a classic Win32 DLL.  (Not a COM server and not a .NET executable).

When your browser starts up (in Firefox, at least), both npctrl.dll (Plug-in) and agcore.dll (Presentation Core) are loaded.  The remaining Silverlight runtime libraries described below are only loaded when you actually load a page containing a Silverlight control.

Silverlight CoreCLR

After your browser has loaded the Silverlight plug-in, it does three basic things:

  • Starts up the Silverlight Common Language Runtime
  • Downloads the .xap file containing your Silverlight control and Application object from the server
  • Instantiates your Application object and loads it

The CoreCLR, or Silverlight Common Language Runtime, is the Silverlight version of the CLR that runs inside the Silverlight plug-in.  (Labeled CLR Execution Engine in the above diagram).  This is the managed environment that your Silverlight applications run inside, similar to the CLR that hosts thick-client .NET applications.

The CoreCLR is implemented in coreclr.dll, also in C:\Program Files\Microsoft Silverlight\2.0.xxxxx.0.  The CoreCLR is based on the same codebase as the desktop version of the CLR, but much smaller, and with features not required in a browser environment removed.  (In the desktop world, the equivalent DLLs are mscoree.dll and mscorwks.dll).

Note: coreclr.dll is also just a “plain old” unmanaged Win32 DLL.  It is the implementation of the .NET CLR, so it does not run in a managed environment itself.

The XAP File

Before Silverlight can run any of your code on the client machine, it has to download it from the server.  Your Silverlight application is packaged into a .xap file.  The .xap file is nothing more than a .zip file that has been renamed.  You can prove this to yourself by building your application and then renaming the resulting .xap file as a .zip file.

silverlight-application-structure

If you look at the files inside your .xap, for a typical wizard-generated Silverlight application, you’ll find two files:

  • AppManifest.xaml
  • SilverlightApplication1.dll

The AppManifest.xaml file is the application manifest, which tells the Silverlight runtime what DLLs are present in this package and which one contains the entry point, or startup object, for your Silverlight application.  For example, you might see something like the following:

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    EntryPointAssembly="SilverlightApplication1"
    EntryPointType="SilverlightApplication1.App"
    RuntimeVersion="2.0.31005.0">
  <Deployment.Parts>
    <AssemblyPart x:Name="SilverlightApplication1" Source="SilverlightApplication1.dll" />
  </Deployment.Parts>
</Deployment>

Note that the manifest tells Silverlight to load the assembly located in SilverlightApplication1.dll and that the startup object is SilverlightApplication1.App, which is the class that derives from System.Windows.Application.

Starting Up

Once the .xap file is downloaded, the CoreCLR can instantiate your object and get things started.  It does this by:

  • Instantiating an instance of your entry point type, e.g. SilverlightApplication1.App
  • Firing the Application.Startup event

Our wizard-generated Silverlight application included wizard-generated code to get everything up and running as follows:

  • During the App constructor
    • Wire a handler for the Application.Startup event
    • Call App.InitializeComponent
  • App.InitializeComponent, also wizard-generated :
  • The handler for the Application.Startup event
    • Instantiates a new Page object  (the actual Silverlight control to be displayed)
    • Sets the RootVisual property of the parent App object to point to the Page
  • During the Page constructor
    • Call Page.InitializeComponent
  • Page.InitializeComponent
    • Calls Application.LoadComponent, reconstituting the Page object from the associated XAML (BAML)

That’s really all there is to it.  At this point, through the magic of the browser plug-in architecture and the fact that the Silverlight CoreCLR is running on the client’s PC, you have a native .NET (Silverlight) application running on the client, hosted in the browser.

References

Debugging Silverlight Applications with windbg and sos.dll – 21 Aug 2008 – Tess Ferrandez
Debugging Tools and Symbols: Getting Started – Windows Hardware Developer Central
Dissecting Silverlight – 1 May 2007 – Ed Burnette
Setting a Silverlight 2 Startup Breakpoint Using WinDBG – 10 Jan 2009 – David Betz
Silverlight Application Services – MSDN
Silverlight Application Structure – MSDN
Silverlight Architecture – MSDN
Silverlight Plug-In Object Reference – MSDN