I'm trying to create my first Revit plugin.
I'm using Revit 2014 and what I want is to place a SINGLE instance of a family loaded from a file. I'm actually using this code:
[TransactionAttribute(TransactionMode.Manual)]
[RegenerationAttribute(RegenerationOption.Manual)]
public class InsertFamily : IExternalCommand
{
readonly List<ElementId> _addedElementIds = new List<ElementId>();
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
UIApplication uiApp = commandData.Application;
Document document = uiApp.ActiveUIDocument.Document;
FamilySymbol family = null;
bool good = false;
using (var trans = new Transaction(document, "inserting family"))
{
trans.Start();
good = document.LoadFamilySymbol(@"my file path.rfa", "my type", new FamilyLoadingOverwriteOption(), out family);
trans.Commit();
}
if (good && family != null)
{
_addedElementIds.Clear();
uiApp.Application.DocumentChanged += applicationOnDocumentChanged;
uiApp.ActiveUIDocument.PromptForFamilyInstancePlacement(family);
uiApp.Application.DocumentChanged -= applicationOnDocumentChanged;
}
return Result.Succeeded;
}
private void applicationOnDocumentChanged(object sender, DocumentChangedEventArgs documentChangedEventArgs)
{
_addedElementIds.AddRange(documentChangedEventArgs.GetAddedElementIds());
}
}
class FamilyLoadingOverwriteOption : IFamilyLoadOptions
{
public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
{
overwriteParameterValues = true;
return true;
}
public bool OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
{
source = FamilySource.Family;
overwriteParameterValues = true;
return true;
}
}
The problem is that the method PromptForFamilyInstancePlacement
allows user to insert multiple instances of the family. I want that the user can insert only ONE instance into the project. I write also the code to have back the inserted instance (using the DocumentChanged
event as you can see), so maybe that handler can be useful in some ways..
Finally I found my own solution (thanks to Jeremy Tammik blog): the only way seems to send the "Esc" + "Esc" key combination to Windows while the command is executing:
I've done a class that handles the low levels messages:
The main code is the following:
In this way only one element is placed and I've it's reference into
el
variable.