Greg Galipeau wrote a thorough post on cleaning up your Web Part Gallery that is the basis for this post. To summarize, Greg shares a Feature Receiver he uses as a generic Feature Receiver for all his WebPart Features that simply removes the WebPart having the same name as the Feature’s DisplayName when the Feature is deactivated.
There are a couple of issues with this though:
- It assumes that the WebPart has the same name as the Feature
- It limits the Feature to deploying just a single WebPart
An alternative approach would be to inspect the Feature’s element definitions and extract the exact WebPart names that were deployed, thus resolving the two issues noted above.
Below is the alternative Feature Receiver (it extends the BaseFeatureReceiver I mentioned in my previous post):
public class WebPartFeatureReceiver : BaseFeatureReceiver<SPSite> { public override void FeatureDeactivating(SPSite site, SPFeatureReceiverProperties properties) { base.FeatureDeactivating(site, properties); var elements = properties.Definition.GetElementDefinitions(CultureInfo.CurrentCulture); var webparts = elements.Cast<SPElementDefinition>() .SelectMany(e => e.XmlDefinition.ChildNodes.Cast<XmlElement>() .Where(n => n.Name.Equals("File")) .Select(n => n.Attributes["Url"].Value) ) .ToList(); var rootWeb = site.RootWeb; var wpGallery = rootWeb.Lists["Web Part Gallery"]; var galleryItems = wpGallery.Items.Cast<SPListItem>() .Where(li => webparts.Contains(li.File.Name)) .ToList(); for (int i = galleryItems.Count - 1; i >= 0; i--) { var item = galleryItems[i]; item.Delete(); } } } |
John Powell
Nice work!
Perry
What namespaces are required?
I can’t figure out what namespace is required to solve the error:
Error 1 ‘Microsoft.SharePoint.Administration.SPElementDefinitionCollection’ does not contain a definition for ‘Cast’ and no extension method ‘Cast’ accepting a first argument of type ‘Microsoft.SharePoint.Administration.SPElementDefinitionCollection’ could be found (are you missing a using directive or an assembly reference?)
Trent
@Perry - Thanks for bringing this up. The ‘Cast’ method is an extension method located in the System.Linq.Enumerable class. You will need to include a using statement for the System.Linq namespace. Extension methods can be a little tricky to track down.
Jan
Hi,
if you change
var wpGallery = rootWeb.Lists[“Web Part Gallery”];
into
var wpGallery = rootWeb.GetList(“/_catalogs/wp”);
It will work in other languages
DenisR
Thanks for the solution.
I would recommend more unified way of loading web parts gallery (without string hardcoding):
var webPartsGallery = rootWeb.GetCatalog(SPListTemplateType.WebPartCatalog);
It works without problems for me.
Your Body, Your Mind, Your Health
Hello, Neat post. There is a problem along with your site in web explorer, could test this? IE still is the market chief and a big component of folks will leave out your great writing due to this problem.