It is another challenge to set values of Revit family parameters (FamilyParameter).
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
As introduced before, the FamilyParameter does not have a value property. In order to get the FamilyParameter value for each FamilyType, a method from the groups AsInteger(), AsDouble(), AsString(), and AsElementId() has to be called based on the StorageType of the FamilyParameter.
So as to set the FamilyParameter value of a specific FamilyType, we have to call the Set() method from another different place, FamilyManager. However, there are still some other issues. The method only accepts FamilyParameter and value arguments but not FamilyType one, so a FamilyParameter value can only be assigned to the current family type (FamilyType) by default.
If we’d like to set the FamilyParameter value of a non current FamilyType, some extra work needs be done. The workaround is to store the FamilyManager.CurrentType somewhere, switch the CurrentType temporarily to the one of interest, set FamilyParameter values, and finally switch the CurrentType back to the original one.
In this post, let’s see how to address all these issues with some real nice C# code. The following help methods can set kinds of FamilyParameter values in all different situations:
public static List<T> RawConvertSetToList<T>(IEnumerable set)
{
List<T> list = (from T p in set select p).ToList<T>();
return list;
}
public static FamilyParameter RawFindFamilyParameter(FamilyManager fm, string parameterName)
{
FamilyParameter fp = RawConvertSetToList<FamilyParameter>(fm.Parameters).
FirstOrDefault(e => e.Definition.Name.Equals(parameterName, StringComparison.CurrentCultureIgnoreCase));
if (fp == null) throw new Exception("Invalid ParameterName Input!");
return fp;
}
public static FamilyType RawFindFamilyType(FamilyManager fm, string familyTypeName)
{
FamilyType famType = RawConvertSetToList<FamilyType>(fm.Types).
FirstOrDefault(e => e.Name.Equals(familyTypeName, StringComparison.CurrentCultureIgnoreCase));
if (famType == null) throw new Exception("Invalid FamilyTypeName Input!");
return famType;
}
public static void RawSetFamilyParameterValue(FamilyManager fm, string familyTypeName, string parameterName, object value)
{
RawSetFamilyParameterValue(fm, RawFindFamilyType(fm,familyTypeName), RawFindFamilyParameter(fm,parameterName) , value);
}
public static void RawSetFamilyParameterValue(FamilyManager fm, FamilyType ft, string parameterName, object value)
{
RawSetFamilyParameterValue(fm, ft, RawFindFamilyParameter(fm, parameterName), value);
}
public static void RawSetFamilyParameterValue(FamilyManager fm, string familyTypeName, FamilyParameter fp, object value)
{
RawSetFamilyParameterValue(fm, RawFindFamilyType(fm, familyTypeName), fp, value);
}
public static void RawSetFamilyParameterValue(FamilyManager fm, FamilyType ft, FamilyParameter fp, object value)
{
FamilyType curFamType = fm.CurrentType;
fm.CurrentType = ft;
try
{
switch (fp.StorageType)
{
case StorageType.None:
break;
case StorageType.Double:
if (value.GetType().Equals(typeof(string)))
{
fm.Set(fp, double.Parse(value as string));
}
else
{
fm.Set(fp, Convert.ToDouble(value));
}
break;
case StorageType.Integer:
if (value.GetType().Equals(typeof(string)))
{
fm.Set(fp, int.Parse(value as string));
}
else
{
fm.Set(fp, Convert.ToInt32(value));
}
break;
case StorageType.ElementId:
if (value.GetType().Equals(typeof(ElementId)))
{
fm.Set(fp, value as ElementId);
}
else if (value.GetType().Equals(typeof(string)))
{
fm.Set(fp, new ElementId(int.Parse(value as string)));
}
else
{
fm.Set(fp, new ElementId(Convert.ToInt32(value)));
}
break;
case StorageType.String:
fm.Set(fp, value.ToString());
break;
}
}
catch
{
throw new Exception("Invalid Value Input!");
}
finally
{
fm.CurrentType = curFamType;
}
}
The following test code can be used to set some FamilyParameter values of some FamilyType objects in a family document, desk.rfa, for example:
…
if (CachedDoc.IsFamilyDocument)
{
FamilyManager fm = CachedDoc.FamilyManager;
RawSetFamilyParameterValue(fm, "60\" x 30\"", "Leg Height", 0.77);
RawSetFamilyParameterValue(fm, RawConvertSetToList<FamilyType>(fm.Types)[0], "Depth", 2.22);
RawSetFamilyParameterValue(fm, "60\" x 30\"", RawFindFamilyParameter(fm,"URL"), "http://spiderinnet.typepad.com");
RawSetFamilyParameterValue(fm, RawConvertSetToList<FamilyType>(fm.Types)[1],
RawConvertSetToList<FamilyParameter>(fm.Parameters).First(e=>e.StorageType==StorageType.String),
"The first family parameter having the String StorageType.");
}
…
FamilyParameter Value Writer of RevitAddinWizard can help do all of these in a configurable and flexible way.
Recent Comments