Friday, July 16, 2010

Silverlight in SharePoint - Option 2 - Custom Web Part Feature

In two previous tutorials I showed how to create a simple Silverlight application, and how to use a Silverlight application inside SharePoint (WSS 3.0 or MOSS 2007) using a Content Editor Web Part.

There are a lot of conflicting and even unclear instructions on the web on how to achieve this.
Thank you Karine Bosch for the excellent post you made available. It is very well structured and helped me immensely in putting together this post for my team. The original blog post which a lot of my information come from can be found at http://karinebosch.wordpress.com/2009/07/17/integrating-silverlight-3-in-sharepoint-2007/

In this tutorial I will show how to develop a proper custom SharePoint web part feature which encapsulates the Silverlight application.


Please note that the example I give is very basic. It will be easy to make the web part more generic - you can add web part properties in which which the user can specify the height, width, and .xap file location. If you add the custom properties you will have a reusable Silverlight container web part.

Important:
This tutorial is for Silverligh 3 - there has been changes from Silverlight version 2 which you need to consider. (SL3 does not contain the System.Web.Silverlight.dll)

Prerequisites:
       Silverlight 3 Tools for Visual Studio (download here)
       SharePoint (WSS 3.0 or MOSS 2007)
       Visual Studio 2008
       A working Silverlight application (see this tutorial to create one)
       WSP Builder (to develop the SharePoint Web Part)

Lets Create our SharePoint Web Part:
Create a new Visual Studio 2008 project.
Select "WSPBuilder" from project type and  "WSP Builder Project" from Templates.














Right-click on the project and add a new item. Select WSPBuilder from Categories and "Web Part Feature" from Templates.













Provide a description for the web part and set the Scope to "Site"












In the Solution Explorer, create a LAYOUTS folder under TEMPLATES and then create 2 new folders under the LAYOUTS folder. Name the 2 new folders "SL3" and "XAPS".
Inside the XAPS folder add an existing working Silverlight 3 application.
(see this tutorial to create one)




















Now we have a structure to build our web part code and we have a Silverlight application which we can display in our web part.
Next we will add two Silverlight helper files. (which enables Web sites to create advanced Silverlight installation and instantiation experiences)

In Windows Explorer locate the Silverlight.js file from the C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Tools folder.
Copy this file to the SL3 folder of your project.
(For more information on Silverligth.js please see this site.)

In Visual Studio Solution Explorer switch-on the "view all files" option, refresh your solution and then right click on Silverlight.js and select "Include in project". Alternatively use the "add to project" functionality.

Right Click on the SL3 folder and select "Add" --> "New Item"
Select Visual C# Items and Select JScript File.
Name the File SharePointSilverLightHelper.js













Once the file is added to your solution, open the file and add the following script to create a Silverlight application based on the silverlight.CreateObjectEx method:
function onSilverlightError(sender, args)
{
var appSource = "";
if (sender != null && sender != 0)
{
 appSource = sender.getHost().Source;
}
var errorType = args.ErrorType;
var iErrorCode = args.ErrorCode;
var errMsg = "Unhandled Error in Silverlight Application " + appSource
+ "\n" ;
errMsg += "Code: "+ iErrorCode + " \n";
errMsg += "Category: " + errorType + " \n";
errMsg += "Message: " + args.ErrorMessage + " \n";
if (errorType == "ParserError")
{
 errMsg += "File: " + args.xamlFile + " \n";
 errMsg += "Line: " + args.lineNumber + " \n";
 errMsg += "Position: " + args.charPosition + " \n";
}
else if (errorType == "RuntimeError")
{
 if (args.lineNumber != 0)
 {
  errMsg += "Line: " + args.lineNumber + " \n";
  errMsg += "Position: " + args.charPosition + " \n";
 }
 errMsg += "MethodName: " + args.methodName + " \n";
}
 throw new Error(errMsg);
}


function createSL(divid, swidth, sheight, source, initparameters)
{
  var pluginid = divid + "Plugin";
  var divElement = document.getElementById(divid);
  var altHTML = divElement.innerHTML;
  if (swidth == null)
   {swidth='100%';}
  if (sheight == null)
   {sheight='750px';
}
  Silverlight.createObjectEx(
 {  source: source,
    parentElement: divElement,
    id: pluginid,
    properties:
    {
     width:swidth, 
     height:sheight,
     minRuntimeVersion:'2.0.31005.0'
  },
   events:
   {
    OnError: onSilverlightError 
   },
   initParams: initparameters
   }
  );
}
 
The solution file structure should look like this:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Save the Visual Studio solution.
 
Next, we will add the web part code to render the Silverlight application inside SharePoint.

Open your web part class (in this example SharePointSilverLightWebPart1.cs) in code view and remove all the unneccesary code so that the class is nice and clean:
using System;
using System.Collections.Generic;

using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Text;

namespace SharePointSilverLightWebPart1
{
   [Guid("848d4aec-5dd2-4b7d-a512-995191a627e8")]
   public class SharePointSilverlightWebPart1 :  
          Microsoft.SharePoint.WebPartPages.WebPart
   {
   }
}

Add the following declaration inside the class:
private LiteralControl silverlightHost;

Add code to the OnPreRender event to register the javascript files.
protected override void OnPreRender(EventArgs e)
{
  base.OnPreRender(e);
  ClientScriptManager cs = Page.ClientScript
  if (!cs.IsClientScriptIncludeRegistered("sl_javascript"))
     cs.RegisterClientScriptInclude(this.GetType(),
     "sl_javascript", "/_LAYOUTS/SL3/Silverlight.js");
  if (!cs.IsClientScriptIncludeRegistered("spsl_javascript"))
    cs.RegisterClientScriptInclude(this.GetType(), 
    "spsl_javascript", /_LAYOUTS/SL3/SharePointSilverLightHelper.js");
}

Call the above javascript from within the CreateChildControls method:
protected override void CreateChildControls()
{
  string xaplocation = null;
  xaplocation = "_LAYOUTS/Xaps/SilverlightApplication1.xap";
  Unit height = new Unit(500);
  string slstring = string.Format("<script 
  type=\"text/javascript\">createSL('silverlightHost', '{0}', 
  '{1}', '{2}', '{3}');</script>", height, height, xaplocation, 
  "");
  silverlightHost = new LiteralControl(string.Format("<div  
  id=\"silverlightHost\" style=\"width:100%; height:100%\"></div>
  {0}", slstring));
  this.Controls.Add(silverlightHost);
}

To test the solution, add a SharePoint site URL to the Debug settings of the project.


















Save the project. Build the project. Use WSP Builder to "Build WSP" and then to "Deploy"
Navigate to the same SharePoint site in I.E. and go to Site Settings -->Site Collection Features. Activate your new feature.














Edit a web part page on your site and add the following web part:










See the new web part containing the Silverlight solution.

Enjoy !!

5 comments:

Johan Olivier said...

Thank you Karine Bosch for the excellent post you made available on this. It is very well structured and helped me immensely in putting together this post for my team. The original blog post which a lot of my information come from can be found at: http://karinebosch.wordpress.com/2009/07/17/integrating-silverlight-3-in-sharepoint-2007/

Anonymous said...

Hi Johan,
Thanks for the credits on your blog! I really appreciate it.
Karine

Anonymous said...

Hi, I followed your steps closely but was unable to get it work. After adding the web part page to my site, all i see is a blank web part. Though if i right click it shows the silverlight link.
I've used the show time app in your previous examples. I got the CEWP working too.
Any idea what could I have missed?

JY

Unknown said...

SharePoint hosting is a new and easier way to integrate web applications with intranets, portals, extranets, and internet sites. It can also be used to set up a task management system and a data repository. See more details at www.cloudappsportal.com

Bieber Black and White said...

Thaanks for sharing

Post a Comment