Silverlight + SharePoint - add to web part gallery
This article covers how to go about packaging a webpart for the Silverlight XAP file and deploy it to Web Part Gallery.
In the previous article I described the steps to create a SharePoint project and deploy the XAP file via a site feature.
Silverlight + SharePoint 2010 - package XAP file in a sandbox WSP Solution
But the user still needs to manually:
- Find the XAP file URL
- Manually insert a Microsoft out of box Silverlight Web Part
- Paste the XAP URL
- Save the Silverlight Web Part (may have to configure InitParams too).
Let's simplify this a little.
Go back to the <Elements> Module, and lets add a webpart
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <Module Name="SilverlightCamera"> <File Path="SilverlightCamera\SilverlightCamera.xap" Url="Style Library/SilverlightCamera.xap" /> <File Path="SilverlightCamera\SilverlightCamera.webpart" Url="_catalogs/wp/SilverlightCamera.webpart" /> </Module> </Elements>
The webpart file itself is very simple: go to Web Parts Gallery, find and export Microsoft's Silverlight.webpart
<?xml version="1.0" encoding="utf-8"?> <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>Cannot import this Web Part.</importErrorMessage> </metaData> <data> <properties> <property name="Title" type="string">Silverlight Camera Web Part</property> <property name="Description" type="string">A web part to display a Silverlight Camera.</property> <property name="Url" type="string">~sitecollection/Style Library/SilverlightCamera.xap</property> <property name="Height" type="int">300</property> </properties> </data> </webPart> </webParts>
You may have noticed that the Url is a SiteCollection relative (~sitecollection/) path, so that no matter whether it's a root site collection or a managed path, we want the user's experience to be perfect.
Unfortunately - that syntax doesn't work, not without one extra hack via the Feature Event Receiver.
Feature Activated Event Receiver
Right click on the feature and add a new event receiver. VS.NET will generate the CS file.
Figure: right click on the feature (.feature) and add an event receiver.
Waldek has a magical event handler code that fixes this problem
http://blog.mastykarz.nl/inconvenient-content-query-web-part-server-relative-urls/
So I'll just post my bit of code here
public override void FeatureActivated(SPFeatureReceiverProperties properties) { // one day when I meet Waldek in person I will buy him beer // http://blog.mastykarz.nl/inconvenient-content-query-web-part-server-relative-urls/ SPSite site = properties.Feature.Parent as SPSite; if (site != null) { SPList webPartsGallery = site.GetCatalog(SPListTemplateType.WebPartCatalog); SPListItemCollection allWebParts = webPartsGallery.Items; SPListItem webPart = (from SPListItem wp in allWebParts where wp.File.Name == "SilverlightCamera.webpart" select wp).SingleOrDefault(); if (webPart != null) { string siteCollectionUrl = site.ServerRelativeUrl; if (!siteCollectionUrl.EndsWith("/")) { siteCollectionUrl += "/"; } string fileContents = Encoding.UTF8.GetString(webPart.File.OpenBinary()); fileContents = fileContents.Replace("~sitecollection/", siteCollectionUrl); webPart.File.SaveBinary(Encoding.UTF8.GetBytes(fileContents)); } } }
During Feature Activated - find the webpart and fix the ~sitecollection marker with the real site collection URL.
Deploy and activate the feature again.
Success! Our .webpart now appearing in the web part gallery.