The Revit API 2012 provides an official way to extend the Element data now. In the old days, we could only create some cumbersome invisible parameters and attach them to the elements where we want to store some extra data. Now the Extensible Storage API can directly address so basic a need for us and has much power.
However, as introduced and demonstrated before, unnecessary complexities, impositions, redundancies and inconsistencies are here and there. In case any of those points as mentioned repeatedly in early posts slip out of our minds, the data storage or read back would just fail. In addition, the out of box supported data types are just a few, far less than enough.
Fortunately, we can create something to get all the inconveniences away and make life easier and better. As demonstrated previously, the super easy and cool Revit Data Operator is the choice. We demonstrated using a custom class to store data of various types before. In this article, let us see how to avoid using the custom class but get the same task done using the super easy & cool Revit Data Operator.
Using the .NET native type ArrayList is the way to go. Here is the test code to store such data:
Reference picked = CachedUiApp.ActiveUIDocument.Selection.PickObject(ObjectType.Element, "Pick a window to attach our data");
using (Transaction trans = new Transaction(CachedDoc, "AttachDataTo"))
{
trans.Start();
ArrayList data = new ArrayList
{
true,
(char)'a',
(byte)111,
(short)22222,
(int)33333333,
(long)44444444444444444,
(float)5.5555e35,
(double)6.6666e166,
(decimal)7.7777777777777777777777777M,
new DateTime(8888, 8, 8, 8, 8, 8),
"Hi guys!"
};
RevitAddinWizard.SuperEasyCoolDataOperator.SetDataToElement(
"DA4AAE5A-4EE1-45A8-B3E8-F790C84CC44F", data, CachedDoc.GetElement(picked));
trans.Commit();
}
Here is the test code to read back the same data from the same Element:
Reference picked = CachedUiApp.ActiveUIDocument.Selection.PickObject(ObjectType.Element, "Pick the window having our data");
using (Transaction trans = new Transaction(CachedDoc, "ReadDataFrom"))
{
trans.Start();
ArrayList data = RevitAddinWizard.SuperEasyCoolDataOperator.GetDataFromElement<ArrayList>("DA4AAE5A-4EE1-45A8-B3E8-F790C84CC44F", CachedDoc.GetElement(picked));
string str = string.Empty;
for (int i = 0; i < data.Count; i++)
{
str += data[i].ToString() +"\n";
}
MessageBox.Show(str, "MyData");
trans.Commit();
}
There is no data class this time.
Here is the core of the Easy & Cool Revit Data Operator:
using System;
using System.Xml.Serialization;
using System.IO;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage; //Revit API 2012 only
namespace RevitAddinWizard
{
public class SuperEasyCoolDataOperator
{
private const string SingleStringFiledName = "SingleStringForAll";
public static void SetDataToElement(string id, object o, Element e)
{
SchemaBuilder sb = new SchemaBuilder(new Guid(id));
sb.SetSchemaName(id.Replace("-", ""));
FieldBuilder fb = sb.AddSimpleField(SingleStringFiledName, typeof(string));
XmlSerializer xml = new XmlSerializer(o.GetType());
using (StringWriter w = new StringWriter())
{
xml.Serialize(w, o);
Entity ent = new Entity(sb.Finish());
ent.Set<string>(SingleStringFiledName, w.ToString());
e.SetEntity(ent);
}
}
public static T GetDataFromElement<T>(string id, Element e)
{
Schema sch = Schema.Lookup(new Guid(id));
string s = e.GetEntity(sch).Get<string>(SingleStringFiledName);
XmlSerializer xml = new XmlSerializer(typeof(T));
using (StringReader r = new StringReader(s))
{
return (T)xml.Deserialize(r);
}
}
}
}
As can be seen, those complexities and impositions all go away. We do not have to specify the same schema GUIDs, scheme names, field names, data types, unit types repeatedly. We do not have to care about all those intermediate objects such as Schema, SchemaBuilder, Field, FieldBuilder, or Entity anymore either.
What we need to care about now are what we really want, the data object, the Element of concern, and the Schema identifier. If they are consistent with each other, it will be very hard to make the data setting or getting fail.
The data can be as simple as a char or complex like an ArrayList.
Life can be so easy like this, huh?
The Revit Addin Wizard (RevitAddinWizard) is going to provide a coder to help generate Extensible Storage code.
Recent Comments