Reputation: 73
I am trying to change a family's part type via Revit's API after changing the family category.
I can retrieve the corresponding parameter and set its value, but (though the transaction is successfully committed) the part type is not changed.
Since the 'Part type' UI element showed an empty string, I checked via "Revit Lookup" what value the parameter had after the attempted change. It was still the old part type which doesn't even exist for that family category.
This is my code so far:
Family f = familyDocument.OwnerFamily;
Category c = f.FamilyCategory;
Parameter p = f.get_Parameter(BuiltInParameter.FAMILY_CONTENT_PART_TYPE);
f.FamilyCategoryId = new ElementId(BuiltInCategory.OST_LightingFixture);
p.Set((int) PartType.Normal);
I also tried it with two separate transactions (first one setting the category, second one setting the part type). No success there either.
Update: Turned out, this code already worked. It was the surrounding code that created the error.
Upvotes: 2
Views: 1356
Reputation: 195
I tried the same in Revit 2018.3 and 2020.2 with success. Just create any family type (I used a lighting fixture template), and insert the following snippet into a new macro.
var f = Document.OwnerFamily;
var c = f.FamilyCategory;
var partTypeParam = f.get_Parameter(BuiltInParameter.FAMILY_CONTENT_PART_TYPE);
using(var t = new Transaction(Document, "Change part type"))
{
t.Start();
f.FamilyCategoryId = new ElementId(BuiltInCategory.OST_DuctAccessory);
partTypeParam.Set((int)PartType.Elbow);
t.Commit();
}
Compile and execute, then observe that the type is changed to duct accessory with part type elbow. Seems to work fine.
The only difference is that you seem to be in a slightly different context. You opened your family from a document context. If there is no non-obvious glitch in your implementation, this may point to an API bug. However, in my experiments this scenario posed no problems, so if there is any bug it cannot be systematic.
My aim was to change an arbitrary window family to a duct elbow. I post only the relevant parts (tested in Revit 2020.2):
internal class FamilyOption : IFamilyLoadOptions
{
bool IFamilyLoadOptions.OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
{
overwriteParameterValues = false;
return true;
}
bool IFamilyLoadOptions.OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
{
source = FamilySource.Family;
overwriteParameterValues = false;
return true;
}
}
public void PartTypeTester()
{
var f = new FilteredElementCollector(Document)
.OfClass(typeof(Family))
.First(ff => ff.Name == "ExampleFamily")
as Family;
var familyDoc = Document.EditFamily(f);
f = familyDoc.OwnerFamily;
var c = f.FamilyCategory;
var partTypeParam = f.get_Parameter(BuiltInParameter.FAMILY_CONTENT_PART_TYPE);
using(var t = new Transaction(familyDoc, "Change part type"))
{
t.Start();
f.FamilyCategoryId = new ElementId(BuiltInCategory.OST_DuctAccessory);
partTypeParam.Set((int)PartType.Elbow);
t.Commit();
}
var opt = new FamilyOption();
f = familyDoc.LoadFamily(Document, opt);
familyDoc.Close(false);
}
Works like a charm. You should not expect the resulting family to behave like a duct accessory though ;-).
Upvotes: 2