September 2010

Volume 25 Number 09

Data-Bound Design - Create a Silverlight 4 Web Part for SharePoint 2010

By Paul Stubbs | September 2010

Microsoft SharePoint 2010 provides a business collaboration platform that’s easy to customize into tools that organizations can depend on and grow with. And when building custom SharePoint solutions, it’s best to take advantage of Silverlight on the front end.

Web Parts are a central part of most SharePoint solutions. When most developers think about using Silverlight in their SharePoint app, using it in Web Parts seems like the obvious direction, and Web Parts are the most common way to create Silverlight applications in SharePoint. But Web Parts aren’t your only option.

You can also use Silverlight in menus, navigation, dialogs, page layouts, master pages—anywhere you can put an object tag. This gives designers a lot of flexibility to create great experiences that feel integrated into SharePoint. With this approach, Silverlight should feel like a natural extension to SharePoint.

The sheer breadth and depth of both the SharePoint platform and Silverlight can be daunting for developers. In fact, it’s common for developers to focus entirely on SharePoint, and for designers to be more familiar with Silverlight. To build a useful SharePoint application, you’ll need to understand both technologies. In this article, I’ll give you an overview of Silverlight integration with SharePoint 2010 and walk you through the basics of using Silverlight in the front end of a SharePoint solution.

Silverlight and SharePoint Workflow

The first step in working with Silverlight and SharePoint together is using the right tools. Visual Studio and Expression Blend are designed to work together, and by using them a Silverlight developer can create a great application using sample data from SharePoint without ever seeing or installing SharePoint. Likewise, a SharePoint developer can integrate the Silverlight application into SharePoint without having to understand or delve into the XAML code.

In this article, I’ll show you how to create a simple Silverlight Web Part that will use the SharePoint client object model for Silverlight to surface a SharePoint list. The application will also be a SharePoint sandboxed application that will enable Site Collection administrators to install and manage the application. The application will also work on SharePoint Online standard accounts.

Figure 1 shows what the final application will look like when it’s running on SharePoint.

image: The Completed Silverlight/SharePoint Application

Figure 1 The Completed Silverlight/SharePoint Application

SharePoint Sample Data

In order for Silverlight and SharePoint developers to work independently, the Silverlight developer will need sample data based on SharePoint data. This will enable the Silverlight developer to be completely free to create an application that will work correctly when plugged into SharePoint.

Expression Blend has a number of features for supporting design time data and sample data. In this example, I will use the XML- formatted sample data. This means the SharePoint developer must create an XML file that represents the SharePoint List that the application will use. You can make this sample data file in any shape you want, but everything becomes much easier if you make it the same shape as what will be returned from SharePoint. For example, the shapes returned using the WCF Data Services entities and the RESTful ListData services of SharePoint are different from the shape of the data returned using the Silverlight client object model.

In this application, I use some of the new data-binding features of Silverlight 4 and the SharePoint client object model for Silverlight. There’s no built-in way to generate this sample data, so you’ll need to create a simple console application to generate the SharePoint sample data. In this case, I created a Visual Basic console application that uses the Microsoft .NET Framework client object model to generate an XML document from the top five list items (see Figure 2).

Figure 2 Console App to Return Data XML

Imports Microsoft.SharePoint.Client
Imports System.Text
Module Module1
  Sub Main()
    Dim context As New _
      ClientContext("http://intranet.contoso.com")
    Dim sampleListItems As ListItemCollection
    Dim sampleList As List = _
      context.Web.Lists.GetByTitle("Contacts")
    Dim qry As New Microsoft.SharePoint.Client.CamlQuery
    qry.ViewXml = "<View><RowLimit>5</RowLimit></View>"
    sampleListItems = sampleList.GetItems(qry)
    context.Load(sampleListItems)
    context.ExecuteQuery()
    'Build the Sample XML Data
    Dim SampleData = _
      <SharePointListItems></SharePointListItems>
    'Iterate through each row using Linq 
    'and XML Literals
    For Each item In sampleListItems
      Dim sampleItem = <ListItem>
        <%= From fieldValue In item.FieldValues _
        Select <<%= fieldValue.Key %>>
        <%= fieldValue.Value %></> %>
        </ListItem>
      SampleData.Add(sampleItem)
    Next
    'Write the file to disk
    System.IO.File.AppendAllText( _
      "C:\SharePointSampleData.xml", _
      SampleData.ToString())
  End Sub
End Module

Once you have the SharePointSampleData.xml file, you’ll be able to use this in Expression Blend as the design time data source.

Designing with Sample Data

With the sample data XML file in hand, you can open Expression Blend and create a new Silverlight 4 application.

On the Data panel, click the Create Sample Data icon in the top-right corner and choose Import Sample Data from XML, then browse to the SharePointSampleData.xml file. You can also leave the block checked to see the sample data while the application is running. Otherwise, you’ll only see the sample data in Blend or in the Visual Studio designer.

Figure 3 shows the Contacts List. The client object model actually returns a dictionary of 45 fields, so you won’t be able to see them all in the figure without scrolling.

image: The Sample Contacts List

Figure 3 The Sample Contacts List

The next step is to create a data-bound list box. In the Data panel, make sure that the List Mode icon is set. You’ll find this in the top-left of the Data panel. Now select the fields you want to appear in the list box. In this case I selected Title, which actually is the first name, and I selected LastName. Drag the fields from the list and drop them onto the design surface. Expression Blend creates a list box and data template data-bound to the fields. Arrange the list box to the left side of the design surface to make space for the details.

Creating the data-bound details is just as easy. Select Details Mode from the icon on the top left of the Data panel window. Select the fields you want to appear as the detail fields. Drag the fields onto the design surface. Expression Blend will create each field bound to the selected item in the list box. If you press F5 and run the application, you’ll see the list box populated with the sample data. As you change the selected item in the list box, you’ll see the details change on the right (see Figure 4).

image: Working on the App in Expression Blend

Figure 4 Working on the App in Expression Blend

You now have a fully functional application data-bound to the SharePoint sample data. As a Silverlight designer, you can continue to test and refine your application without ever knowing anything about SharePoint. In this example, I have done a little more design work and arranged all of the fields and added the Sketch theme from the Silverlight Toolkit.

The Silverlight Web Part

At this point, the Silverlight developer can hand the project file over to the SharePoint developer. This is possible because Expression Blend and Visual Studio share the same project files. The SharePoint developer opens the project in Visual Studio 2010 and can see all of the parts of the application so he can work on the application in the Visual Studio designer (see Figure 5).

image: Working on the App in Visual Studio

Figure 5 Working on the App in Visual Studio

The first thing the SharePoint developer will need to do is add an empty SharePoint project to the existing solution that contains the Silverlight project. He’ll use this SharePoint project to deploy the Silverlight application file (.xap) and to create a Silverlight Web Part to host the Silverlight application.

Visual Studio 2010 makes doing both of these tasks easy compared to building SharePoint solutions in the past. Right-click on the solution and choose Add New Project. Browse to the SharePoint 2010 templates and select Empty SharePoint Project. In the New Project wizard, be sure to keep the default selection for creating the project as a sandboxed solution. This is a best practice and gives you the most flexible and secure deployment options. Silverlight also works well with sandboxed solutions because Silverlight runs on the client and isn’t limited to many of the restrictions as server-side code running in the sandbox.

Although the order really doesn’t matter, it’s better to create the Web Part first. This will enable you to nest the module that will deploy the Silverlight .xap file under the Web Part. This just keeps the project structure well organized and easier to follow as your solutions get larger.

Add the Web Part to your SharePoint project by right-clicking on the project and choosing Add New Item. Select Web Part from the SharePoint 2010 template folder. This will create a new empty Web Part in your project.

A Web Part consists of just three items. The first is the Elements.xml file. This is a SharePoint solution file that describes the items in a feature.

The second is the Web Part definition file, which has a .webpart extension. This file is deployed to the SharePoint Web Parts gallery and defines the code for the Web Part and all of the properties of the Web Part.

The third file is the code file. All three of these files are placed under a folder in the project structure.

So this is where it gets interesting. All of the files that are added to the project when you create a new Web Part are needed if you’re creating a Web Part from scratch. In this case, you don’t need to use all of the auto-generated files because SharePoint already ships with a Silverlight Web Part. What you want to do is to build on this existing Web Part. To do that you simply need to make the .webpart file point to the code for the Silverlight Web Part and include all of the properties.

Create a copy of the built-in Silverlight Web Part .webpart file. There’s actually an automatic way to do this. In SharePoint add a Silverlight Web Part to any page. While in design mode, click on the drop-down menu of the Web Part and choose Export. This lets you make a copy of the .webpart file that you can add to your project. Now just change a few properties such as the path to the Silverlight application, title, description, and so on. Also, because you’re now using the code for the Web Part from the built-in Microsoft.SharePoint.dll, you no longer need the .cs file for the Web Part. You can simply delete this file. Figure 6 shows an example of what your .webpart file will look like once you add it to your project.

Figure 6 Excerpt from the Default .webpart File

<webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="Microsoft.SharePoint.WebPartPages.SilverlightWebPart, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <importErrorMessage>$Resources:core,ImportErrorMessage;
      </importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name="HelpUrl" 
                  type="string" />
        <property name="AllowClose" 
                  type="bool">True</property>
        <property name="ExportMode" 
                  type="exportmode">All</property>
        <property name="Hidden" 
                  type="bool">False</property>
        <property name="AllowEdit" 
                  type="bool">True</property>
        <property name="Description" 
                  type="string">Contacts Web Part</property>
        ...
        <property name="Height" 
                  type="unit">480px</property>
        <property name="ChromeType" 
                  type="chrometype">None</property>
        <property name="Width" 
                  type="unit">640px</property>
        <property name="Title" 
                  type="string">Contacts Demo</property>
        <property name="ChromeState" 
                  type="chromestate">Normal</property>
        <property name="TitleUrl" 
                  type="string" />
        <property name="Url" 
                  type="string">
        ~site/_catalogs/masterpage/SilverlightApplication1.xap
        </property>
        <property name="WindowlessMode" 
                  type="bool">True</property>
      </properties>
    </data>
  </webPart>
</webParts>

Deploying Silverlight to SharePoint

At this point, you have a fully functional Silverlight application and a Web Part to host the Silverlight application. Now you need to create a SharePoint module to deploy the actual Silverlight .xap file to SharePoint.

Visual Studio 2010 has built-in functionality to do this, so hooking everything up is straightforward. Right-click on your Web Part folder and choose Add New Item. Select Module template from the SharePoint 2010 templates.

A new module, by default, contains an elements.xml file, just like the one you added to the Web Part feature. It also contains a sample.txt file. Delete the sample.txt file, as you will not need it.

There’s a special way to add a reference to the Silverlight application in your project. Select the Module folder in the Solution Explorer and view the properties. Click on the Project Output References property to open the Project Output References dialog. In the dialog, click the Add button to add a new reference. In the Project Name drop-down menu, choose the Silverlight application project. Set the Deployment Type to Ele­ment File and close the dialog.

You’ve now added a reference to the Silverlight app. This works much like standard project references where the Silverlight project will build before the SharePoint project and the output of the Silverlight project (the .xap file) will be copied to the SharePoint project and built into the SharePoint solution file (the .wsp file).

The last step is to set the deployment path of the Silverlight application. This is the location to which the .xap file will be copied and the location from which the Web Part will load the application.

Open the elements.xml file under the Module folder. Set the URL property of the file element to be the same as the URL property in the .webpart file. In this case you will deploy to the master page gallery so set the value to:

~site/_catalogs/masterpage/
  SilverlightApplication1.xap

Note the tilde at the beginning of the path is a special SharePoint wildcard to indicate the root of the site.

Now deploy the solution to SharePoint to verify that everything is set up correctly. Set the SharePoint project as the default startup project and press F5. Visual Studio will build and package the solution. Although Visual Studio will open the SharePoint site and attach the debugger, you still need to add the Web Part to the page. I find the easiest way to do this while developing my solutions is to add the Web Part to a new Site Page.

Client Object Model

With everything in place, you’re ready to wire up the Silverlight application to actual SharePoint data. SharePoint 2010 includes client-side object models for the CLR, Silverlight and ECMAScript. These enable easy access using a familiar object model to SharePoint data, such as Lists and Libraries.

In this particular case you’re building a Silverlight app, so you need to add a reference to the Silverlight client object model. The Silverlight client object model is made up of two files, Microsoft.Share­Point.Client.Silverlight.dll and Microsoft.SharePoint.Client.Silverlight.Runtime.dll. These files are located in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin\.

Once you have the references added, you can write the code to retrieve the contacts from the Contacts list. Start by adding a using statement for Microsoft.SharePoint.Client to the top of the MainPage.xaml.cs. Then you’ll need to define a couple of class-level fields to hold the returned results. You also need to handle the page-loaded event, which is used to load the List data:

public partial class MainPage : UserControl {
  ClientContext ctx;
  ListItemCollection contactsListItems;
  public MainPage() {
    InitializeComponent();
    this.Loaded += MainPage_Loaded;
  }
  void MainPage_Loaded(
    object sender, RoutedEventArgs e) {
    LoadList();
  }
}

Next, implement the LoadList method to retrieve the data from SharePoint. First, get a reference to the current client context. The static method ClientContext.Current returns a context to the site in which the Web Part is loaded. You then call GetByTitle to get a reference to the Contacts list. The Load method will add the request to the query. Then call ExecuteQueryAnsc to make the call to the SharePoint Server:

void LoadList(){
  ctx = ClientContext.Current;
  if (ctx != null) { //null if not in SharePoint
    List contactsList = 
      ctx.Web.Lists.GetByTitle("Contacts");
    contactsListItems =
      contactsList.GetItems(
      CamlQuery.CreateAllItemsQuery());
    ctx.Load(contactsListItems);
    ctx.ExecuteQueryAsync(
      ContactsLoaded, ContactsLoadedFail);
  }
}

Calls to the server in Silverlight are asynchronous. The Exe­cute­­QueryAsync method takes two callback delegates, one for succeeded and one for failed results. In the ContactsLoaded callback method, you data bind the results to the XAML that the Silverlight designer created in the beginning of the article. In the succeeded callback, all you need to do is set the ItemsSource property of the list box to the contacts collection returned by the client object model. The callback also occurs on a background thread, so you’ll need to update the property inside of the Dispatcher’s BeginInvoke method:

// ContactsLoaded
void ContactsLoaded(object sender, 
  ClientRequestSucceededEventArgs args) {
  //call back on the UI thread
  this.Dispatcher.BeginInvoke(() => {
    ContactsListBox.ItemsSource = contactsListItems;
  });
}

I left the failed callback for you to implement.

There’s one more thing you need to do before running the application: you need to change the way Silverlight binds to the data source. Remember, in the beginning of the article, I created an XML file that represented the data from SharePoint, but this isn’t exactly the same data because the SharePoint client object model actually returns a collection of dictionary field values.

One of the new features of Silverlight 4 is the ability to bind to indexers. This means you can data bind to the dictionary values returned by the client object model using the name of the key value as a string to the binding command. Unfortunately, there isn’t a good way to deal with this complex dictionary-based sample data, but it’s easy enough to change the bindings back and forth using the Visual Studio find and replace tools. For example, you need to change the Text="{Binding Title}" to Text="{Binding Path=FieldValues[Title]}". Do this for all of the fields. I’ve included the regular expression code to switch back and forth in the sample code for this article.

Once you’ve changed all of the bindings to use the Silverlight 4 indexer binding, you’re ready to run the application. Browse to the site page you created to host the Silverlight application. It should look like Figure 1 that you saw in the beginning of the article.

Dynamically Loaded Client Object Model

At this point your application is complete, but there’s one more thing I want to show you. This is a change to SharePoint since the beta version. When I created a reference to the Silverlight client object model by browsing to the files using the Visual Studio Add References dialog, by default, Visual Studio includes these two files in the .xap package that it builds. This adds an additional 407KB to your Silverlight package.

A better option is to dynamically load these assemblies at run time. This enables the browser to cache these common files, reducing your application size and the load times while increasing the performance of your applications.

Since the SharePoint beta release, SharePoint packaged the two client object model files into a single .xap file called Microsoft.SharePoint.Client.xap. This file is in the same location as the other client object model files, C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin. You still need to add a reference to the client object model files because this will give you the IntelliSense and compile support you need. But you’ll need to select each file in the references folder of your Silverlight application and set the Copy Local property to false. Setting this to false will prevent Visual Studio from adding these files to your .xap package.

Next, you need to add code to dynamically load the client object model assemblies. This is very generic code and can be used in any Silverlight application on any .xap package with little modification. Start by changing the page-loaded event to call the code to download and load the assemblies. In this example, you pass a callback delegate to the LoadList method. This way, when the assemblies are loaded and ready to use, you’ll then load the list data from SharePoint, like so:

void MainPage_Loaded(
  object sender, RoutedEventArgs e) {
  LoadClientOM loadClientOM = 
    new LoadClientOM(delegate() { LoadList(); });
  loadClientOM.Run();
}

Add a new class file to your project called LoadClientOM.cs and add the code shown in Figure 7. This code uses the WebClient to download the .xap package from /_layouts/clientbin/Microsoft.SharePoint.Client.xap. Once the package is downloaded, you load each assembly from the package.

Figure 7 Loading Microsoft.SharePoint.Client.xap

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.IO;
using System.Windows.Resources;
using System.Reflection;
namespace SilverlightApplication1 {
  public class LoadClientOM {
    private bool isDownloaded = false;
    private Action action;
    public LoadClientOM(Action action) {
      this.action = action;
    }
    public void Run() {
      WebClient client = new WebClient();
      client.OpenReadCompleted += 
        new OpenReadCompletedEventHandler(
        client_OpenReadCompleted);
      client.OpenReadAsync(new Uri(
        "/_layouts/clientbin/Microsoft.SharePoint.Client.xap", 
        UriKind.Relative));
    }
    void client_OpenReadCompleted(object sender, 
      OpenReadCompletedEventArgs e) {
      Stream assemblyStream;
      AssemblyPart assemblyPart;
      assemblyStream = Application.GetResourceStream(
        new StreamResourceInfo(e.Result, "application/binary"), 
        new Uri("Microsoft.SharePoint.Client.Silverlight.Runtime.dll", 
        UriKind.Relative)).Stream;
      assemblyPart = new AssemblyPart();
      Assembly b = assemblyPart.Load(assemblyStream);
      assemblyStream = Application.GetResourceStream(
        new StreamResourceInfo(e.Result, "application/binary"), 
        new Uri("Microsoft.SharePoint.Client.Silverlight.dll", 
        UriKind.Relative)).Stream;
      assemblyPart = new AssemblyPart();
      Assembly a = assemblyPart.Load(assemblyStream);
      this.isDownloaded = true;
      if (action != null) {
        action();
      }
    }
  }
}

You can now run the application again. You’ll see that the application looks exactly the same, but now you’re loading the Silverlight client object model dynamically at run time from the server. It may be difficult to detect in this simple application, but you should also see better performance loading them dynamically.


Paul Stubbs is a Microsoft technical evangelist who focuses on the information worker development community for SharePoint and Office, Silverlight and Web 2.0 social networking. He’s authored three books about solution development with Office, SharePoint and Silverlight. Read his blog at blogs.msdn.com/b/pstubbs.

Thanks to the following technical experts for reviewing this article: Mike Morton*,* John Papa and Unni Ravindranathan


About the Author