We have addressed converting Parameter and FamilyParameter to Shared Parameter previously. Now let’s see how to convert Project Parameter to Shared Parameter.
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
Before creating the specific code for the Project Parameter Converter, we need to put some Coders together first that we introduced and demonstrated before. They will save us a lot of precious time and avoid duplicate effort.
Here they are:
#region From ProjectParameter Infoer
public class RawProjectParameterInfo
{
public static string FileName { get; set; }
public string Name { get; set; }
public BuiltInParameterGroup Group { get; set; }
public ParameterType Type { get; set; }
public bool ReadOnly { get; set; }
public bool BoundToInstance { get; set; }
public string[] BoundCategories { get; set; }
public bool FromShared { get; set; }
public string GUID { get; set; }
public string Owner { get; set; }
public bool Visible { get; set; }
}
public static List<RawProjectParameterInfo> RawGetProjectParametersInfo(Document doc)
{
RawProjectParameterInfo.FileName = doc.Title;
List<RawProjectParameterInfo> paramList = new List<RawProjectParameterInfo>();
BindingMap map = doc.ParameterBindings;
DefinitionBindingMapIterator it = map.ForwardIterator();
it.Reset();
while (it.MoveNext())
{
ElementBinding eleBinding = it.Current as ElementBinding;
InstanceBinding insBinding = eleBinding as InstanceBinding;
Definition def = it.Key;
if (def != null)
{
ExternalDefinition extDef = def as ExternalDefinition;
bool shared = extDef != null;
RawProjectParameterInfo param = new RawProjectParameterInfo
{
Name = def.Name,
Group = def.ParameterGroup,
Type = def.ParameterType,
ReadOnly = def.IsReadOnly,
BoundToInstance = insBinding != null,
BoundCategories = RawConvertSetToList<Category>(eleBinding.Categories).Select(c => c.Name).ToArray(),
FromShared = shared,
GUID = shared ? extDef.GUID.ToString() : string.Empty,
Owner = shared ? extDef.OwnerGroup.Name : string.Empty,
Visible = shared ? extDef.Visible : true,
};
paramList.Add(param);
}
}
return paramList;
}
public static string RawParametersInfoToCSVString<T>(List<T> infoList, ref string title)
{
StringBuilder sb = new StringBuilder();
PropertyInfo[] propInfoArrary = typeof(T).GetProperties();
foreach (PropertyInfo pi in propInfoArrary)
{
title += pi.Name + ",";
}
title = title.Remove(title.Length - 1);
foreach (T info in infoList)
{
foreach (PropertyInfo pi in propInfoArrary)
{
object obj = info.GetType().InvokeMember(pi.Name, BindingFlags.GetProperty, null, info, null);
IList list = obj as IList;
if (list != null)
{
string str = string.Empty;
foreach (object e in list)
{
str += e.ToString() + ";";
}
str = str.Remove(str.Length - 1);
sb.Append(str + ",");
}
else
{
sb.Append((obj == null ? string.Empty : obj.ToString()) + ",");
}
}
sb.Remove(sb.Length - 1, 1).Append(Environment.NewLine);
}
return sb.ToString();
}
#endregion
#region From SharedParameter Creator
public static List<T> RawConvertSetToList<T>(IEnumerable set)
{
List<T> list = (from T p in set select p).ToList<T>();
return list;
}
public static Definition RawCreateSharedParameter(RvtApplication app, string name, string group, ParameterType type, bool visible)
{
DefinitionFile defFile = app.OpenSharedParameterFile();
if (defFile == null) throw new Exception("No SharedParameter File!");
DefinitionGroup dg = RawConvertSetToList<DefinitionGroup>(defFile.Groups).FirstOrDefault(g => g.Name == group);
if (dg == null) dg = defFile.Groups.Create(group);
Definition def = RawConvertSetToList<Definition>(dg.Definitions).FirstOrDefault(d => d.Name == name);
if (def != null) return def; //dg.Definitions.Erase(def); //ReadOnly Exception!!
def = dg.Definitions.Create(name, type, visible);
return def;
}
#endregion
With all the above code handy, it becomes a pretty easy task to create some code to convert a particular Project Parameter or all Project Parameter instances of a Revit Project Document to shared parameters:
public static void ConvertProjectParameterInfoToSharedParameter(Document doc, RawProjectParameterInfo info, bool visibilityOverride)
{
if (info.Type == ParameterType.Invalid)
{
info.Type = ParameterType.Text;
}
RawCreateSharedParameter(doc.Application, info.Name, "For_" + doc.Title, info.Type, visibilityOverride);
}
public static void ConvertProjectParameterToSharedParameter(Document doc, string name, bool visibilityOverride)
{
List<RawProjectParameterInfo> pList = RawGetProjectParametersInfo(doc);
List<RawProjectParameterInfo> pListOfInterest = pList.FindAll(p => p.Name == name);
foreach (RawProjectParameterInfo info in pListOfInterest)
{
ConvertProjectParameterInfoToSharedParameter(doc, info, visibilityOverride);
}
}
public static void ConvertAllProjectParametersToSharedParameters(Document doc, bool visibilityOverride)
{
List<RawProjectParameterInfo> pList = RawGetProjectParametersInfo(doc);
foreach (RawProjectParameterInfo info in pList)
{
ConvertProjectParameterInfoToSharedParameter(doc, info, visibilityOverride);
}
}
A few points may be worth of mentioning here:
- The ParameterType of some valid Project Parameter instances may be Invalid! We assign the most popular Text ParameterType to the Project Parameter in this case to resolve the creation problem of the affected shared parameters.
- The name of the DefinitionGroup of all the shared parameters will be defaulted as For_<Project Document Name>.
- Since the visibility information of the original shared parameter definitions if any is not easy to find back, we give a chance in these methods to override the visibility for the shared parameters.
The following test code can exercise the methods:
ConvertProjectParameterToSharedParameter(CachedDoc, "URL", true);
ConvertAllProjectParametersToSharedParameters(CachedDoc, true);
In terms of details of the various coders referenced in this post please refer to previous posts for ideas and code examples.
Project Parameter Converter of RevitAddinWizard can create all these in a second.
Recent Comments