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.
![clip_image002[5] clip_image002[5]](https://static1.squarespace.com/static/5527bff2e4b0b430660b0d10/5527c30de4b030eeeef09715/5527c30ee4b030eeeef09b54/1295364888093/Windows-Live-Writer-14e81274d27e_20FD-)
Success! Our .webpart now appearing in the web part gallery.