Setting Up a Bare Minimum WPF Development Environment

Microsoft now offers Visual Studio 2010 in an Express edition–which is free.  You’re limited to a single language, but you can develop WPF applications using Express.

In this post, I walk through the exact steps to install and use Visual Studio 2010 Express (C# edition).  The install was done a clean Windows 7 machine.

To start with, go to the Microsoft Express download site.  Click on the link for the development language of your choice (e.g. C#, VB, C++) and then select a language (e.g. English).  The install package will start downloading.

This will download file named vcs_web.exe.  Double-click on the file to start the install process.

Click Yes on the UAC dialog.

Installation files will be extracted:

You’ll get to the first install dialog.  Be a good citizen and agree to send information about your “setup experience” back to Microsoft.  After all, they’re giving you a free product.

Carefully read every word in the license agreement and then agree to it.  (Yes, of course I’m being tongue-in-cheek when I say to read every word).

You can optionally decide to install Silverlight and/or SQL Server Express.  For this example, I’ll install Silverlight only.

Decide what directory to install into.  The default is fine.

Things start downloading and installing.  Sit back and wait–this will take a while.

You may need to restart in the middle of the installation.

After the reboot, the install continues.

Your patience will eventually be rewarded, as the installation completes.

Oh wait–one more restart, just for good measure.

Now you’ll see Visual Studio C# 2010 Express in your Start Menu.

When you start Visual Studio for the first time, you’ll see the Start Page.  You can click on the New Project link to create your first project.  The New Project dialog lists the various types of projects that you can create:

  • Windows Forms Application
  • WPF Application
  • Console Application
  • Class Library
  • WPF Browser Application
  • Empty Project

(Notice that we can’t create Silverlight projects–the Silverlight option that we chose during the install likely just installed the Silverlight runtime, rather than the Silverlight tools for Visual Studio).

At this point, you’re all set.  You have everything that you need, to create Windows client applications–either Windows Forms or WPF.  If you’re building something new, you’ll likely want to start with WPF.

Advertisements

Generate From Usage in Visual Studio 2010

Visual Studio 2010 comes with the new Generate From Usage feature.  Let’s take a quick look at how it works.

The basic idea is simple.  You can use classes and their methods and properties before you’ve actually implemented them.  This helps support test-driven development, in which you normally write your test cases first and get them to run by stubbing out all of the actual production code.

Top-Down Design

You might also use the Generate From Usage feature as you implement your code, writing the code in a top-down fashion.  The idea of top-down design is that you start writing your application at the highest level, creating abstractions for all lower-level constructs that are too complex to implement at the highest level.

Generate From Usage Example

Let’s look at an example.  In this example, I have a function that takes some basic info about a book as input and then expects to persist that information in a Book object in a database.  Let’s assume that we haven’t yet created the Book class, or any of its methods or properties.  Then my function might look something like this in Visual Studio:

Notice that since we haven’t yet defined the Book class or any of its methods, Visual Studio underlines the Book identifier with a little red squiggle.

If I hover the mouse over the squiggle, I get a nice error message telling me that Book is not defined.

Now let’s just left-click on the squiggle.  A little blue underline shows up at the start of the unknown identifier.

If you now hover over the blue underline, you’ll see a little smart tag show up.

If you click on the smart tag, you’ll see two options: Generate class for ‘Book’ and Generate new type…

The simplest thing to do at this point is to select the first option, to generate a new Book class.  If we pick that option, a Book.cs file will be automatically added to our project, with a skeleton implementation of the Book class.

namespace WpfApplication3
{
    class Book
    {
    }
}

Notice, however, that focus stays in the original code editor window, so you can continue working in the same place.  At this point, the red squiggle on the Book class has disappeared, since we now have a basic implementation of the class.  Also notice that we see a whole bunch of new squiggles.  Now that Book is a valid class, Visual Studio knows that it does not contain any of the properties or methods that we are referencing.

Detour–Generate New Type

Let’s go back a step.  What would have happened if we’d selected the Generate new type… option?  Let’s try it.  If you pick this option, you’ll get a dialog asking you to enter some more details on the class that you want to create.

Basically, you can choose this option if you want to specify some additional details about the class that you want to create, including the file name, which project to create it in, and the access modifier for the class.  You can also have Visual Studio create other constructs, like a struct or an interface.

Return From Detour

Now let’s go back to the EnterBook() method that we were working on.  Remember that after we generated the Book class, we got a bunch more squiggles.  As before, if you hover over the squiggle, you’ll see what the error is.  For example, we didn’t add a non-default constructor to the Book class, so we’re seeing an error when we try to construct the object.

Once again, we can use the Generate From Usage feature to generate some code for us.  As before, click on the squiggle and then click on the smart tag.  Now we see an option to generate the constructor.

Once again, if you click on this option, nothing will appear to happen in the code window where you are working.  But if you open the Book class, you’ll see that it now has a new constructor.

class Book
{
    private string Title;

    public Book(string Title)
    {
        // TODO: Complete member initialization
        this.Title = Title;
    }
}

But notice that Visual Studio went even one step further.  It also created a private field named Title for us and set the value of the field to the book title that we passed into the constructor.  This is (almost) exactly what we want.  (Likely, we’ll want to convert the private field into a property).

Encapsulating a Field

Actually, since I mentioned it, let’s go ahead and convert this field to a property.  First, I’ll rename the field, from “Title” to “_title”.  I do this because I’m going to want my property to be named Title.  So I want my backing variable (the existing field) to be named something else.  Now just right-click on the field, select Refactor and then select Encapsulate Field.

You’ll then get a dialog asking you to confirm the name of the field.

Click OK and then go back to look at your new code in the Book class.

class Book
{
    private string _title;

    public string Title
    {
        get { return _title; }
        set { _title = value; }
    }

    public Book(string Title)
    {
        // TODO: Complete member initialization
        this._title = Title;
    }
}

Perfect!

Generating a Property Stub

Now let’s go back to our EnterBook function again and once again click on a smart tag.  This time, click on the tag for the line where we’re trying to set the LastName property.  You’ll see the following:

Notice that we’re always seeing options that are appropriate for the type of object that is undefined.  In this case, Visual Studio sees that we are using LastName as a property, so it offers to create it for us.

If you select the option to generate a property stub, rather than a field stub, you’ll get what you expect in your Book class:

    public string LastName { get; set; }

Visual Studio created a new property named LastName and automatically generated the get and set accessors for the property.  Also notice that it figured out the correct type for the property, based on the variable that we were assigning to it.

Generating a Method

We’ll do just one more example.  As expected, if you click on the smart tag at the point where we’re trying to call a Save method, Visual Studio will offer to generate the method.

As you’d expect, Visual Studio once again generates a stub in the Book class for us:

    internal void Save()
    {
        throw new NotImplementedException();
    }

Wrapping Up

There you have it–a quick tour through the new Generate From Usage feature in Visual Studio 2010.  Once you get into the habit of using it, you can be quite a bit more productive when coding in a top-down fashion.

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.