- Silverlight Web Parts
- Manually Building a Silverlight Web Part
- Visual Studio Silverlight Web Parts Extension
- Building a Silverlight Web Part
- Building a Custom Silverlight Web Part
- Connecting Web Parts
- Summary
Building a Custom Silverlight Web Part
A custom Silverlight Web Part is very similar to the Silverlight Web Part you created in the previous section. The only difference is that it uses a sandboxed Visual Web Part to host the Silverlight application as opposed to the built-in Silverlight Web Part control that ships with SharePoint. Using the sandboxed Visual Web Part has some advantages over the built in Silverlight Web Part host, such as not having the five-second timeout. A custom Silverlight Web Part enables you to interact with the web part page that the Silverlight application is hosted on. You see an example of this later in the chapter. You can also include other HTML items with your custom web part such as JavaScript, CSS, and images.
Create a Custom Silverlight Web Part just like you did in the previous section. Add a Silverlight project and a SharePoint project to a Visual Studio solution. In this case you can use the SLGrid project that you used in the previous section. After you create the two projects, you need to connect them together. Open the Add New Item dialog for the SharePoint project. Choose the Silverlight Custom Web Part project item, as shown in Figure 5.12.
Figure 5.12 Add a Custom Silverlight Web Part
The Visual Studio project has the same items as it did when you added a Silverlight Web Part. There is a module that deploys the Silverlight .xap file. There is a wiki test page that hosts the Silverlight Web Part. The difference is now there is a sandboxed Visual Web Part instead of just a .webpart definition file. The sandboxed Visual Web Part Project Item template comes from the Visual Studio 2010 SharePoint Power Tools extension, which you installed as a prerequisite to the Silverlight Web Parts extension. The sandboxed Visual Web Part is implemented as an ASP.NET user control (.ascx). What makes this user control special is that normally you cannot deploy user controls as part of a SharePoint sandboxed solution because the .ascx file must be written to the _layouts directory in SharePoint. But because this is a sandboxed solution, you are not allowed to do this. To work around this problem the Visual Studio team wrote a custom sandboxed Visual Web Part that compiles the .ascx control to code before deploying it to SharePoint. This avoids the file restrictions of the sandbox as there is nothing to write to the file system. The Silverlight Web Part extension takes advantage of this special Visual Web Part to host the Silverlight application, as shown in Figure 5.13. This is important because Silverlight runs on the client, so there should never be a restriction that it cannot run in a sandboxed solution. Also by using the Visual Web Part it makes it easier for developers to extend the web part using the Visual Design tools in Visual Studio.
Figure 5.13 Custom Silverlight Web Part
The sandboxed Visual Web Part contains the code to host the Silverlight application. Open this page in Visual Studio to see the hosting code. This code is the same code that the Silverlight project generates in the test pages when you build the project. The only change to that generated code is the insertion of SharePoint tokens for the source and initparams.
First is the Silverlight error handling code in Listing 5.6. This code is unchanged from what is generated by the Silverlight project system.
Listing 5.6. Error Handling Script in the Custom Silverlight Web Part
<!-- Silverlight Error Handler --> <script
type
="text/javascript"> function onSilverlightError(sender, args) { var appSource = ""; if (sender != null && sender != 0) { appSource = sender.getHost().Source; } var errorType = args.ErrorType; var iErrorCode = args.ErrorCode; if (errorType =="ImageError"
|| errorType =="MediaError"
) { return; } 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); }<
/script>
The next section of code, shown in Listing 5.7, is the code that inserts Silverlight on the page. The two properties to call out are source and initParams. The source property is the URL to the Silverlight .xap file host in SharePoint. The initParams are parameters passed to the Silverlight application when it is started. There is one special parameter called MS.SP.url. The MS.SP.url parameter is used by the client object model to set the ClientContext.Current value. Without the MS.SP.url parameter, ClientContext.Current returns null. You should always pass this parameter if you want to access the client context, even if you are creating your own Silverlight Web Parts.
Listing 5.7. Silverlight Object Tag in the Custom Silverlight WebPart
<!-- Silverlight Control --> <div
id
="silverlightControlHost"style
="position
:relative;height
:480px; width:640px"> <object
data
="data:application/x-silverlight-2,"type
="application/x-silverlight-2"width
="100%"height
="100%"> <param
name="source" value="<%= Microsoft.SharePoint.SPContext.Current.Web.Url %>/_catalogs/masterpage/ClientBin/SLGridCustomWebPartPackage/SLGrid.xap" /> <param
name
="onError"value
="onSilverlightError" /> <param
name
="background"value
="white" /> <param
name
="minRuntimeVersion"value
="4.0.50401.0" /> <param
name
="autoUpgrade"value
="true" /> <param
name
="initParams"value
="MS.SP.url=<%= Microsoft.SharePoint.Utilities.SPHttpUtility.HtmlEncode(Microsoft.SharePoint.SP Context.Current.Web.Url) %>" /> <a
href
="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50401.0"style
="text-decoration
: none"> <img
src="https://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
>
You could run the project at this point. There is nothing more you need to do to deploy this to SharePoint. But let's take a look at one more advantage of using the custom Silverlight Web Part by extending the application to interact with the user control hosting the Silverlight application. Open the Visual Web Part in the Visual Studio Code Editor and add the following div tag below the closing script tag and above the Silverlight object tag:
<div
id
="SLDiv"></div
>
This div tag could really go anywhere on the page. In this example it appears above the Silverlight application within the web part. Next you need to add some code to the SLGrid application's MainPage.xaml.cs file to populate this div tag with the currently selected user. In the Loaded event of the MainPage, add the code to handle the selection changed event of the data grid as shown in Listing 5.8.
Listing 5.8. MainPage_Loaded Event
void
MainPage_Loaded(object
sender,RoutedEventArgs
e) { clientContext =ClientContext
.Current; listDataGrid.SelectionChanged +=new
listDataGrid_SelectionChanged; RefreshData(); }
The selection changed event handler retrieves the current list item from the data grid. Note that because we are using data binding with the client object model, the list item is an actual SharePoint List Item object. Extract the FullName field from the list item and call the SetSLDiv() function. SetSlDiv() uses the Silverlight HTML Bridge to get a reference to the SLDiv tag that you added to the user control. When you have a reference to the div tag, you can set the innerhtml property with the FullName of the list item, and you could even set other values such as the style properties. Add the code in Listing 5.9 to the MainPage.xaml.cs file in theSilverlight application SLGrid.
listing 5.9. Displaying SharePoint ListItem Properties in a Div Tag
void
listDataGrid_SelectionChanged(object
sender,SelectionChangedEventArgs
e) {ListItem
selectedListItem = (ListItem
)listDataGrid.SelectedItem;string
fullName = "No Selected Item"
;if
(selectedListItem !=null
) fullName = selectedListItem["FullName"
].ToString(); SetSLDiv(string.Format("<h1>{0}</h1>"
, fullName)); }private void
SetSLDiv(string
InnerHTML) {HtmlElement
SLDiv =HtmlPage
.Document.GetElementById("SLDiv"
);if
(SLDiv !=null
) { SLDiv.SetProperty("innerhtml"
, InnerHTML); SLDiv.SetStyleAttribute("color"
,"blue"
); } }
Run the project by pressing F5, which compiles both the Silverlight project and the SharePoint project. It packages the SharePoint project, adding a copy of the Silverlight .xap file to the package. F5 also deploys the package to the SharePoint sandboxed Solution Gallery, activates the solution, launches Internet Explorer, and attaches the Visual Studio debugger. You can see in Figure 5.14 that Bob is selected in the Silverlight grid, that div tag has been set with his full name, and the color has been set to blue.
Figure 5.14 Silverlight interacting with HTML
The custom Silverlight Web Part is as easy to use as the built-in Silverlight Web Part and opens up a number of new scenarios.