I added text dialogues to my code to give indication where the broken state is occurring. Am I using the PromptForFamilyInstancePlacement method incorrectly so that it's causing me to get stuck? I can place as many instance as I want, but I cant get out of the placement state unless I hit ESC, which causes the user aborted error.
Here is the code at the moment -
#region Namespaces
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
#endregion
namespace Get_Family_Information
{
[Transaction(TransactionMode.Manual)]
public class Command1 : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
// This is a variable for the Revit application
UIApplication uiapp = commandData.Application;
// This is a variable for the current Revit model
Document doc = uiapp.ActiveUIDocument.Document;
// Retrieve the family name and family symbol
string targetFamilyName = "RECEPT - Standard - Type";
string targetFamilySymbol = "General - 180 VA";
// Retrieve the specified family and symbol
Family family = GetFamily(doc, targetFamilyName);
FamilySymbol symbol = GetFamilySymbol(family, targetFamilySymbol);
if (family != null && symbol != null)
{
try
{
// Place the family symbol in "Place Component" mode
uiapp.ActiveUIDocument.PromptForFamilyInstancePlacement(symbol);
return Result.Succeeded;
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
TaskDialog.Show("Info", "Placement operation canceled by the user.");
return Result.Cancelled;
}
catch (Exception ex)
{
TaskDialog.Show("Error", ex.Message);
return Result.Failed;
}
}
else
{
TaskDialog.Show("Error", "Family or symbol not found.");
return Result.Failed;
}
}
private Family GetFamily(Document doc, string familyName)
{
return new FilteredElementCollector(doc)
.OfClass(typeof(Family))
.FirstOrDefault<Element>(
e => e.Name.Equals(familyName)) as Family;
}
private FamilySymbol GetFamilySymbol(Family family, string symbolName)
{
if (family != null)
{
return new FilteredElementCollector(family.Document)
.OfClass(typeof(FamilySymbol))
.Cast<FamilySymbol>()
.FirstOrDefault(s => s.FamilyName.Equals(family.Name) && s.Name.Equals(symbolName));
}
return null;
}
public static String GetMethod()
{
var method = MethodBase.GetCurrentMethod().DeclaringType?.FullName;
return method;
}
}
}
The ultimate goal is to have a code that I can adapt to place any specified family type with just one button input. I am new to Revit API so perhaps I am making this task more complicated that it has to be by pursuing this route? I am open to redirection if I am trying to reinvent the wheel.