This post is in continuation to the existing blog post on this topic - Deleting a Collection of Elements/Families: The Correct Approach.
As you might have noticed in the previous blog post on this topic, the unexpected behavior is due to deleting (or infact any changes to the Element table in Revit’s database) during any active iteration itself. This typically affects FilteredElementIterator, FilteredElementIdIterator, and foreach loops over the FilteredElementCollector.
One approach that was mentioned in the previous post was to collect all the elements that fit the criteria and then performing the delete after the iteration is completed. If the deletion has to happen during the iteration itself, the other approach is to use use FilteredElementCollector.ToElements(), ToElementIds(), or LINQ methods like ToList<Type>() to get a standalone collection, then iterate that collection. The following code snippet illustrates the alternative approach.
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace Revit.SDK.Samples.HelloRevit.CS
{
[Transaction(TransactionMode.Manual)]
public class Command : IExternalCommand
{
public Result Execute(ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
UIApplication uiApp = commandData.Application;
Document doc = uiApp.ActiveUIDocument.Document;
FilteredElementCollector coll =
new FilteredElementCollector(doc)
.OfClass(typeof(Family));
using (Transaction trans = new Transaction(doc, "Delete"))
{
trans.Start();
foreach (Family fam in coll.ToElements())
{
if (fam.FamilyCategory.Name.Equals("Generic Annotations")
&& fam.Name.Equals("XYZ"))
{
doc.Delete(fam);
}
}
trans.Commit();
}
return Result.Succeeded;
}
}
}