We talked about programmatically converting parameters from one to another manually before. Now let’s see how Parameter Converter of RevitAddinWizard can assist us to hit the target with just a few mouse clicks. The Parameter Converter can be found from either Revit Addin Coder sub-menu under the Tools or from Revit Addin Coder toolbar.
Revit Parameter Organizer can organize various Revit parameters such as Shared Parameters, Family Parameters, Project Parameters and Built-in Parameter in many good ways.
When the menu item or the tool button is clicked, the Parameter Converter window will show up:
If the Parameter (to SharedParameter) Converter is selected from the check list box and a class is chosen from the combo box, a Parameter to SharedParameter Converter will be created and added into the class automatically. The entire converter code and necessary namespaces and class declarations have been appended below:
#region Namespaces
using System;
using System.Text;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
using System.IO;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.UI.Events;
using Autodesk.Revit.Collections;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.Utility;
using RvtApplication = Autodesk.Revit.ApplicationServices.Application;
using RvtDocument = Autodesk.Revit.DB.Document;
#endregion
namespace RevitAddinCS1
{
class ParameterConverter
{
public class RawParameterInfo
{
public string Name { get; set; }
public string ID { get; set; }
public string Value { get; set; }
public BuiltInParameterGroup Group { get; set; }
public ParameterType Type { get; set; }
public StorageType Storage { get; set; }
public string Unit { get; set; }
public bool Shared { get; set; }
public bool ReadOnly { get; set; }
}
public static string RawGetDUTString(Parameter p)
{
string unitType = string.Empty;
try { unitType = p.DisplayUnitType.ToString(); }
catch { }
return unitType;
}
public static List<RawParameterInfo> RawGetParametersInfo(Element e)
{
List<RawParameterInfo> paramList =
(from Parameter p in e.Parameters
select new RawParameterInfo
{
Name = p.Definition.Name,
ID = p.IsShared ? p.GUID.ToString() : (p.Definition as InternalDefinition).BuiltInParameter.ToString(),
Value = p.AsValueString(),
Group = p.Definition.ParameterGroup,
Type = p.Definition.ParameterType,
Storage = p.StorageType,
Unit = RawGetDUTString(p),
Shared = p.IsShared,
ReadOnly = p.IsReadOnly,
}).ToList();
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();
}
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;
}
public static void ConvertParameterToSharedParameter(Element e, string name, bool convertSharedOnly, bool visibilityOverride)
{
List<RawParameterInfo> pList = RawGetParametersInfo(e);
List<RawParameterInfo> pListOfInterest = pList.FindAll(p => p.Name == name);
foreach (RawParameterInfo info in pListOfInterest)
{
if (info.Type == ParameterType.Invalid)
{
info.Type = ParameterType.Text; //It's weird that a valid Parameter can have an invalid ParameterType! We set it as the most popular Text type in this case. Otherwise, the DefinitionGroup.Definitions.Create() would fail!
}
if (convertSharedOnly)
{
if (info.Shared)
{
RawCreateSharedParameter(e.Document.Application, name, "For_" + e.Category.Name, info.Type, visibilityOverride);
}
}
else
{
RawCreateSharedParameter(e.Document.Application, name, "For_" + e.Category.Name, info.Type, visibilityOverride);
}
}
}
public static void ConvertAllParametersToSharedParameters(Element e, bool convertSharedOnly, bool visibilityOverride)
{
List<RawParameterInfo> pList = RawGetParametersInfo(e);
foreach (RawParameterInfo info in pList)
{
if (info.Type == ParameterType.Invalid)
{
info.Type = ParameterType.Text;
}
if (convertSharedOnly)
{
if (info.Shared)
{
RawCreateSharedParameter(e.Document.Application, info.Name, "For_" + e.Category.Name, info.Type, visibilityOverride);
}
}
else
{
RawCreateSharedParameter(e.Document.Application, info.Name, "For_" + e.Category.Name, info.Type, visibilityOverride);
}
}
}
}
}
We would not create test command to extercise these parameter converter code here. In case needed, please refer to earlier posts for ideas and code examples.
As mentioned, Parameter Converter of RevitAddinCoder can create all these code automatically in a second.
Links to some related articles:
Parameter of Revit API - Other Parameter Conversion Scenarios
Parameter Converter - Parameter to Shared Parameter
Parameter Converter - FamilyParameter to Shared Parameter
Recent Comments