RIA

Light Up SharePoint With Silverlight 2 Web Parts

Steve Fox and Paul Stubbs

This article is based on a prerelease version of Silverlight 2. All information is subject to change.

This article discusses:
  • Creating a Silverlight media player
  • Creating the Web Part
  • Deploying to a SharePoint site
  • Troubleshooting the app
This article uses the following technologies:
Silverlight 2, SharePoint

Contents

Creating the Media Player
Coding the Application UI
The Application Code
Creating and Deploying the Web Part
Adding the Application to the SharePoint Site
Troubleshooting

In the world of Web-based application development, users are demanding ever-improved application experiences. Further, the demands of these Web-based applications go beyond supporting a single browser technology or platform. If you are building a Web app today, you need technologies that support not only a way to deliver a more compelling user experience, but also that enable developers to deliver this experience quickly to multiple technologies and audiences.

Silverlight 2 is one example of a technology that enables robust Web application development opportunities. Silverlight is a cross-browser, cross-platform plug-in that provides developers access to a rich programming model for building Web-based user experiences.

SharePoint is another technology that is frequently being used for Web-based application development. Companies that invested in SharePoint for intranet development now want to extend this technology out to externally facing Web sites. Together, Silverlight and SharePoint provide a simple, yet powerful, infrastructure for building intranet and extranet applications with sophisticated user interface designs and interactions.

In this article, we'll discuss one of the key ways in which you can use SharePoint and Silverlight together by integrating a Silverlight application within a SharePoint Web Part. We start by walking you through building a fairly simple media application using Silverlight 2 Beta 2 (see Figure 1). We'll then show how you can use the SharePoint Web Part as a wrapper for your Silverlight application. This is an interesting approach because it enables you to not only create isolated hosted applications, but also interconnect the Web Parts through the native SharePoint object model—for example, through a provider/consumer model.

fig01.gif

Figure 1 Silverlight WMV Player Web Part (Click the image for a larger view)

Creating the Media Player

Silverlight 2, in beta 2 as we go to press, is quite an evolution from Silverlight 1.0. For example, Silverlight 2 supports managed code, so in addition to JavaScript, you can now use Visual Basic and C# in your applications. Further, Silverlight 2 ships with a set of controls and facilitates the extension of controls to make the job of creating Silverlight-based user interfaces much easier. The designer experience is now much better and is supported by both a UI designer tool within Visual Studio 2008 and Expression Blend.

To prepare your environment to build Silverlight applications for SharePoint, make sure you have the following installed:

  • Windows Server 2003 or Windows Server 2008
  • Windows SharePoint Services 3.0 and SP1
  • Microsoft Office SharePoint Server 2007 and SP1
  • Visual Studio 2008 Professional Edition
  • Silverlight Tools Beta 2 for Visual Studio 2008
  • Silverlight 2 Beta 2 Runtime
  • Windows SharePoint Services 3.0 Tools: Visual Studio Extensions, Version 1.2

After you've set up your environment, open Visual Studio 2008 and create a new project. In either the C# or Visual Basic nodes, you'll find a new project node called Silverlight, which contains two project templates: one to create a Silverlight application and another to create a Silverlight class library (see Figure 2).

fig02.gif

Figure 2 Silverlight Application New Project Template (Click the image for a larger view)

For the sample app, we selected the Silverlight application template, provided a name (MediaPlayer in our case), and accepted the other default options. After completing those steps and clicking OK, you will be prompted to either add a new Web to the solution or to dynamically generate an HTML test page for hosting Silverlight within the project. Select the first choice (adding a new Web to the solution), again accepting the default options. When finished, your solution will consist of both the Silverlight project and the hosting Web application (as opposed to just an HTML page).

In our example, you can see these two projects in the MediaPlayer solution. The first is a Web site called MediaPlayerWeb. This is the test Web site that you will use to develop and test your Silverlight application. The second project is the Silverlight application called MediaPlayer. For this article, we'll focus on the Page.xaml and the Page.xaml.cs files in the MediaPlayer project.

In Silverlight 2, the UI is generated using an XML-based declarative language called XAML—the same language used to create Windows Presentation Foundation (WPF) UI for client applications. Page.xaml contains the XAML code that defines the UI, while Page.xaml.cs contains the codebehind for the application.

You can have only one Page.xaml.cs file, but you can have multiple XAML files that can be managed through the central Page.xaml file. You might do this if you want to manage separate Silverlight controls in one Page.xaml.

Coding the Application UI

Visual Studio 2008 provides a split design/XAML view when you open XAML files. Additionally, in Silverlight 2 Beta 2, you can drag controls from the toolbox and drop them on the XAML view. (Dragging controls to the designer surface is not supported in Visual Studio 2008, although you can drag and drop to the designer surface in Expression Blend.)

The UI that we created for MediaPlayer is deliberately simple in order to illustrate the fundamental aspects of integration. Figure 3 shows the XAML code that represents the UI for the Silverlight application. We're using StackPanel elements to contain and position other controls within the UI. One hosts a MediaElement, the element that will play the WMV file and a Slider element that represents the timeline for the short movie. Another hosts Button, ToggleButton and CheckBox elements, which will provide playing, pausing, stopping, and muting functionality.

Figure 3 Media Player XAML

<UserControl x:Class="MediaPlayer.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="500">

    <StackPanel Grid.Row="1" 
                Margin="20,10,20,10" 
                Background="White" 
                Visibility="Visible">

        <MediaElement x:Name="moviePlayer" 
                      Source="Bear.wmv"
                      Margin="5">                     
        </MediaElement>

        <Slider x:Name="timeline" 
                ValueChanged="timeline_ValueChanged"
                Maximum="1"  
                Margin="5" >
        </Slider>
        <StackPanel Orientation="Horizontal" 
                    HorizontalAlignment="Center">
            <Button x:Name="movieStop"
                    Content="Stop" 
                    Height="25"
                    Width="40"

                    Click="movieStop_Click"
                    Margin="5">
            </Button>
            <ToggleButton x:Name="moviePlay" 
                          Content="Play" 
                          Height="25"
                          Width="40"

                          Click="moviePlay_Click"
                          Margin="5">
            </ToggleButton>
            <CheckBox x:Name="movieMute"
                      Content="Sound On"
                      Click="movieMute_Click">
            </CheckBox>
        </StackPanel>
    </StackPanel>
</UserControl>

One of the key properties that you'll want to take note of in the XAML-based UI is the x:Name property. This represents the name provided for the control, which you can use to manipulate it from the codebehind. Also note the events that correspond to some of the controls in the XAML, such as the button's click=moviePlay_Click, which will call the moviePlay_Click method in the codebehind when clicked.

In the XAML code, we configure the MediaElement control to play the movie Bear.wmv. You can load your own movie from the ClientBin folder, but you'll need to make sure you change the Source property in the XAML to reflect the name of the file you add to your project. Also note that you can provide an HTTP reference to a location of a WMV file, such as using a picture library as a repository for your movies in your SharePoint site.

Note that when creating the event handlers within the Page.xaml file for each of the event handlers (such as Click="movieMute_Click"), if you type Click and then use IntelliSense to add the event handlers, Visual Studio will automatically add the stub methods for your event handlers in the Page.xaml.cs file.

Before we move on to the codebehind, let's take a quick look at the Expression Blend view of this same code. We did all of the coding within Visual Studio 2008, but you can also use Expression Blend to create a UI that can subsequently be integrated into your Silverlight project in Visual Studio. After opening the page in Expression Blend (see Figure 4), you can then add items to the Silverlight application, save the file, and then switch back to Visual Studio 2008, which will prompt you to reload the changes from Expression Blend in your Visual Studio 2008 project. (To open in Expression, right-click Page.xaml and select Open in Expression Blend.)

fig04.gif

Figure 4 Project View in Expression Blend (Click the image for a larger view)

The Application Code

To add codebehind for the Silverlight application, right-click the Page.xaml file in the Solution Explorer and click View Code. You can also expand the Page.xaml node, right-click the Page.xaml.cs file, then select View Code. The code in this view corresponds to the UI we built earlier—this is where we set specific properties of the Silverlight controls. Figure 5 shows the code that we added to the Page.xaml.cs file.

Figure 5 Media Player Codebehind

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

        private void timeline_ValueChanged(
          object sender, RoutedPropertyChangedEventArgs<double> e) {
            long ticks = (long)((sender as Slider).Value * 
              this.moviePlayer.NaturalDuration.TimeSpan.Ticks);
            TimeSpan movieTimespan = new TimeSpan(ticks);
            this.moviePlayer.Position = movieTimespan;
            if (this.moviePlayer.CurrentState == MediaElementState.Playing) {
                this.moviePlay.IsChecked = true;
                this.moviePlay.Content = "Pause";
            }
        }

        private void movieStop_Click(object sender, RoutedEventArgs e) {
            this.timeline.Value = 0;
            this.moviePlayer.Stop();
            this.moviePlay.Content = "Play";
        }
        private void moviePlay_Click(object sender, RoutedEventArgs e) {
            if (moviePlay.IsChecked == true) {
                moviePlay.Content = "Pause";
                this.moviePlayer.Play();
            }
            else {
                moviePlay.Content = "Play";
                this.moviePlayer.Pause();
            }
        }

        private void movieMute_Click(object sender, RoutedEventArgs e) {
            if (movieMute.IsChecked == true) {
                movieMute.Content = "Sound On";
                this.moviePlayer.IsMuted = true;
            }
            else {
                movieMute.Content = "Sound Off";
                this.moviePlayer.IsMuted = false;
            }
        }
    }
}

You'll note that in the codebehind there are a number of methods, all of which correspond to the event handlers that we added to the controls in the XAML code. For example, in this code the movieStop_Click method responds to the user clicking the Stop button, which then sets the timeline value to 0 (in other words, back to the start of the movie) and changes the text on the Play button (which changes from Pause to Play depending on what state it's originally in).

This codebehind also responds to the user clicking the Play/Pause toggle button, which calls the appropriate Play and Pause methods and sets the text on the toggle button. The user can also interact with the slider control, which will jump the movie forward to a specific point—the equivalent to a fast-forward/rewind functionality. And finally, the user can mute the movie by clicking the Mute checkbox.

At this point, you can debug the Silverlight application by pressing F5 on your keyboard or clicking Debug | Start Debugging from the Visual Studio project menu. This will invoke your default browser and then load the Silverlight application. You may see a warning that debugging is not enabled. Click OK to have Visual Studio modify the web.config file to enable debugging. If everything is working correctly, the WMV file (in our case, Bear.wmv) will load and begin playing. You can alter the play state by clicking Stop, Pause, or using the slider control. You can also affect the sound by checking the Mute checkbox.

While the Silverlight application is now working, you need to make sure you complete one more step before moving on to integrating it with SharePoint. This step is to ensure that the XAP file, the archive that contains your built Silverlight application, is located where the SharePoint Web Part can pick it up and load it.

The XAP file contains all of the core application files for your Silverlight application. Because the XAP file is essentially an archive of the built project files, you can rename the XAP file with a .zip extension and then open it up to see the files that are contained within the XAP package.

When you open up the MediaPlayer.xap file, you will see several different files: the core DLLs for the project and an AppMani­fest.xaml file. The DLLs in the archive are a combination of the code that you create (in this example, the DLL we created was MediaPlayer.dll) and Microsoft DLLs required to run your compiled assembly. The AppManifest.xaml file is generated and lists any dependencies from your project. Here are the contents of the AppManifest.xaml file from the MediaPlayer example discussed in this article, which contains a number of key references specific to the deployment of the Silverlight application:

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  EntryPointAssembly="MediaPlayer" 
  EntryPointType="MediaPlayer.App" 
  RuntimeVersion="2.0.30523.6">
  <Deployment.Parts>
    <AssemblyPart x:Name="MediaPlayer" Source="MediaPlayer.dll" />
    <AssemblyPart x:Name="System.Windows.Controls.Extended" 
      Source="System.Windows.Controls.Extended.dll" />
  </Deployment.Parts>
</Deployment>

It shows the name of the assembly (MediaPlayer), the Silverlight runtime version we used to compile our application (2.0.30523.6), and then lists out the required assemblies, which are also contained within the XAP archive.

Make sure that the XAP file is copied to a location within your SharePoint site. For the MediaPlayer example, we created a folder called ClientBin in the root virtual directory of our SharePoint site. You could alternatively copy the XAP file to a SharePoint document library or to the _layouts folder on your SharePoint server. Within ClientBin we created a folder called XAP, which contains all of the XAP files (or Silverlight applications we're building and integrating with SharePoint). You need to reference this location when creating an instance of the Silverlight control in the SharePoint Web Part project. You also need to make sure that when you update and recompile your Silverlight application, you don't forget to copy the most recent XAP file into the appropriate directory.

After you've copied your XAP file to a location on your server, you're now ready to move onto creating the SharePoint Web Part host container for your Silverlight application.

Renaming a Web Part

If you accepted the default name for your Web Part project, the project shell contains a Web Part called WebPart1. You could keep this, but you probably want a more descriptive name for your Web Part.

To do this, right-click the existing Web Part (WebPart1) and select Delete. Next click the WSP tab and delete everything under WebPart1WebPart. (If the WSP view—the view of the Web Part package as it will be deployed to SharePoint—is not displayed, from the main Visual Studio menu click View, Other Windows, and select WSP View.) After confirming the deletion of the Web Part, right-click the project in Solution Explorer and then select Add New Item. In the Add New Item dialog, select the SharePoint node and then select Web Part. Provide a more intuitive name for the Web Part.

foxstubbs.silverlight.sidebar.gif

Adding a New Web Part to the Project (Click the image for a larger view)

Creating and Deploying the Web Part

To create the Web Part, open Visual Studio and open a new SharePoint Web Part project template (see Figure 6). In our example, we've named the new Web Part project MediaPlayerWebPart.

fig06.gif

Figure 6 Web Part Project Template (Click the image for a larger view)

After you've added your new Web Part, you'll need to add two references to the project before you can add code. The first reference is the System.Web.Extensions DLL, and the second is the System.Web.Silverlight DLL. To add code to the Web Part, right-click the Web Part code file (for example MediaPlayerWebPart.cs) and click View Code. Figure 7 shows the code that we added to the Web Part project.

There are two key items to call out. The first is the fact that we are using the ScriptManager object to render the Silverlight application. This is because the Silverlight application has a dependency on the AJAX ScriptManager control, so an instance of the ScriptManager object needs to first be added to the project.

The second is the instantiation of the Silverlight control. In the code you see in Figure 7, myMediaCtrl represents the instance of our Silverlight control (effectively the Silverlight media player we created). After you create a new instance of the control, you'll need to set a number of properties. Very important among these properties is the Source property, which points to the location of the XAP file and then loads that within the Web Part.

Figure 7 Media Player Web Part

namespace MediaPlayerWebPart {
    [Guid("7e7ef885-130a-45e6-ab14-15f344b1939d")]
    public class MediaPlayerWebPart : 
      System.Web.UI.WebControls.WebParts.WebPart {
        public MediaPlayerWebPart() {
        }

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);

            ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
            if (scriptManager == null) {
                scriptManager = new ScriptManager();
                this.Controls.Add(scriptManager);
            }
        }

        protected override void CreateChildControls() {
            System.Web.UI.SilverlightControls.Silverlight myMediaCtrl = 
              new System.Web.UI.SilverlightControls.Silverlight();
            myMediaCtrl.ID = "myMediaPlayer";
            myMediaCtrl.Source = "/ClientBin/XAP/MediaPlayer.xap";
            myMediaCtrl.Width = new System.Web.UI.WebControls.Unit(900);
            myMediaCtrl.Height = new System.Web.UI.WebControls.Unit(650);

            this.Controls.Add(myMediaCtrl);
        }
    }
}

With the code added, you are now ready to complete the second step: configuring the Web Part project for deployment. To do this, open the project's the Properties view and click the Debug tab. Check the Start Browser with URL checkbox, and then enter the root URL for your SharePoint site (for example, http://spvm).

To test the deployment of the Web Part, click Build, and then Deploy Solution. This automatically creates a WSP package (the CAB equivalent for SharePoint assembly deployments) that contains all of the files that are required to deploy the Web Part assembly to SharePoint, deploys the solution files to the appropriate places on your SharePoint site, and then stops and restarts the Internet Information Services (IIS) Web application.

If you are trying to deploy on Windows Server 2008 with UAC turned on, you need to run Visual Studio as Administrator or you will get an "Object reference not set to an instance of an object" error. Assuming everything was configured correctly, you'll now be able to add the Web Part to a site within SharePoint, thus the last step in your integration between SharePoint and Silverlight.

Adding the Application to the SharePoint Site

At this point, you've created the Silverlight application and you've created and deployed the Web Part container for the Silverlight application. The last remaining step is to create a site that can host the Web Part. Before you do this, though, there are a couple of items you will want to verify.

The first thing to verify is that you've installed System.Web.Silverlight.dll in the global assembly cache (GAC). If it is not, install it from the installation location \Program Files\Microsoft SDKs\Silverlight\v2.0\Libraries\Server.

The second thing to verify is that the web.config file in your SharePoint root directory has all of the necessary elements to support a Silverlight application and the Silverlight application is marked as a safe control. The following illustrates the safe control entry for the MediaPlayerWebPart in the web.config file (which is automatically added when you build and deploy your project to your SharePoint site):

<SafeControl Assembly="MediaPlayerWebPart, 
             Version=1.0.0.0, 
             Culture=neutral,    
             PublicKeyToken=9f4da00116c38ec5" 
             Namespace="MediaPlayerWebPart" 
             TypeName="MediaPlayerWebPart" 
             Safe="True" />

While we won't talk exhaustively about the web.config file, when you're trying to make sure that the web.config file in the root directory of the SharePoint site supports the Silverlight application, the easiest way to do this is to review the web.config file that is built as a part of the Silverlight project and make sure all of those elements exist in the web.config that resides in the root folder of your SharePoint site. If all of these elements are not present, your Silverlight application will not appear in the SharePoint Web Part.

You are now ready to create the SharePoint site that will host the Silverlight-based Web Part. To do this, navigate to your SharePoint site. We created a separate test site for our Silverlight application called Media Player. To create a site, navigate to the home page of your SharePoint site and click Site Actions | Site Settings. Under Site Administration, click Sites and Workspaces. Within the Sites and Workspaces page, click Create. Provide a name, description, and type of site (we selected Blank site) and URL for your site, and then click Create.

When the new site is created, SharePoint will automatically load it for you. Click Site Actions and Edit Page. In the site, click Add a Web Part, which invokes the Web Part Gallery (see Figure 8). Scroll down until you find the Web Part project you added to SharePoint (for example MediaPlayerWebPart), select the checkbox, and then click Add. This will add the Silverlight media player application into SharePoint by way of the Web Part as a host container. The Silverlight application will respond the same as when you were debugging it within Visual Studio 2008—it just appears as a Web Part within SharePoint. After you've added the Web Part to SharePoint, try out the different controls within the Silverlight application to make sure they all work.

fig08.gif

Figure 8 Web Part Gallery (Click the image for a larger view)

Further Reading on Web Parts

SharePoint and Silverlight Blueprints

ssblueprints.net/sharepoint

Silverlight Home Page

silverlight.net

SharePoint Development Resources

MSSharePointDeveloper.com

Troubleshooting

After you've added the Web Part to SharePoint, be sure to try out the different controls within the Silverlight application to make sure they all work. As you know, development is not always without some degree of troubleshooting, so we'll offer a couple of things to look out for as you integrate your Silverlight applications with SharePoint.

If you get network errors when loading media, this is often because the deployed assembly cannot find the media. If the media path is relative, it is relative to the XAP location, so make sure the media loads properly in the Silverlight application.

Make sure the XAP Source location is correct within the Web Part file. Many times, we've seen the case where the Web Part loads without any Silverlight application. This is usually because the Web Part cannot find the XAP file. Also, when you update your Silverlight application, make sure to recopy the newest version of the XAP file into the source location that you've specified in the Web Part project.

If you have successfully added the Web Part, but the Silverlight still does not show up, then you should double-check the web.config file that is in your root SharePoint directory and make sure it not only has the Web Part marked as a safe control (as discussed earlier) but also has all of the necessary elements in order to support the Silverlight appli­ca­tion.

Steve Fox is a Technical Evangelist with the Developer Platform Evangelism (DPE) team at Microsoft. He spends most of his time evangelizing Office and SharePoint development and working with companies that want to use them in their development efforts. Steve has coauthored a number of books including Professional Microsoft SharePoint Development Using Silverlight 2. You can check out his blog at blogs.msdn.com/steve_fox.

Paul Stubbs is an Architect in the Platform Architecture Team, where he focuses on solutions architecture with an emphasis on information worker productivity, business-to-customer solutions, and Web 2.0 social networking. He has authored two books on solution development using Microsoft Office, several articles for MSDN Magazine, and has also spoken at Microsoft Tech•Ed and Tech Ready conferences. Read Paul's blog at blogs.msdn.com/pstubbs.