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.
As introduced many times before, the extensible data storage is achieved by a few new API classes such as Schema, SchemaBuilder, FieldBuilder, and Entity, and identified by schema GUIDs. Though Schema has many other properties such as schema name, add in client id, writable, readable, and so on, the GUID is the key which can not be ignored or even duplicated. That is why in our Revit Data Operator and Revit Data Extension as demonstrated also many times in various aspects before, some of those properties are skipped and some are automatically taken care of.
In this article, let us see how the schema list is maintained by Revit .NET API. The Revit Extensible Storage API provides a helper method, Schema.ListSchemas(), which seems to give us a good schema list all the time. Let us double check this through a simple experiment:
private void SchemaInOut(Reference picked)
{
PrintcCurrentSchemaList();
using (Transaction trans = new Transaction(CachedDoc, "AddDataTo"))
{
trans.Start();
SchemaBuilder sb = new SchemaBuilder(new Guid("1A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F"));
sb.SetSchemaName("SchemaTest");
FieldBuilder fb = sb.AddSimpleField("FieldTest", typeof(int));
Schema schema = sb.Finish();
Entity ent = new Entity(schema);
ent.Set<int>("FieldTest", 123);
CachedDoc.GetElement(picked).SetEntity(ent);
trans.Commit();
}
System.Diagnostics.Debug.WriteLine("Schema 1A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been added.");
PrintcCurrentSchemaList();
using (Transaction trans = new Transaction(CachedDoc, "AddDataTo"))
{
trans.Start();
SchemaBuilder sb = new SchemaBuilder(new Guid("2A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F"));
sb.SetSchemaName("SchemaTest");
FieldBuilder fb = sb.AddSimpleField("FieldTest", typeof(int));
Schema schema = sb.Finish();
Entity ent = new Entity(schema);
ent.Set<int>("FieldTest", 123);
CachedDoc.GetElement(picked).SetEntity(ent);
trans.Commit();
}
System.Diagnostics.Debug.WriteLine("Schema 2A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been added.");
PrintcCurrentSchemaList();
using (Transaction trans = new Transaction(CachedDoc, "RemoveDataFrom"))
{
trans.Start();
Schema sch = Schema.Lookup(new Guid("1A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F"));
CachedDoc.GetElement(picked).DeleteEntity(sch);
trans.Commit();
}
System.Diagnostics.Debug.WriteLine("Schema 1A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been deleted.");
PrintcCurrentSchemaList();
using (Transaction trans = new Transaction(CachedDoc, "AddDataTo"))
{
trans.Start();
SchemaBuilder sb = new SchemaBuilder(new Guid("3A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F"));
sb.SetSchemaName("SchemaTest");
FieldBuilder fb = sb.AddSimpleField("FieldTest", typeof(int));
Schema schema = sb.Finish();
Entity ent = new Entity(schema);
ent.Set<int>("FieldTest", 123);
CachedDoc.GetElement(picked).SetEntity(ent);
trans.Commit();
}
System.Diagnostics.Debug.WriteLine("Schema 3A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been added.");
PrintcCurrentSchemaList();
using (Transaction trans = new Transaction(CachedDoc, "RemoveDataFrom"))
{
trans.Start();
Schema sch = Schema.Lookup(new Guid("3A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F"));
CachedDoc.GetElement(picked).DeleteEntity(sch);
trans.Commit();
}
System.Diagnostics.Debug.WriteLine("Schema 3A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been deleted.");
PrintcCurrentSchemaList();
using (Transaction trans = new Transaction(CachedDoc, "RemoveDataFrom"))
{
trans.Start();
Schema sch = Schema.Lookup(new Guid("2A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F"));
CachedDoc.GetElement(picked).DeleteEntity(sch);
trans.Commit();
}
System.Diagnostics.Debug.WriteLine("Schema 2A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been deleted.");
PrintcCurrentSchemaList();
}
private void PrintcCurrentSchemaList()
{
IList<Schema> list = Schema.ListSchemas();
System.Diagnostics.Debug.WriteLine("All Schema returned by the Schema.ListSchemas():");
foreach (Schema sch in list)
{
System.Diagnostics.Debug.WriteLine(" "+sch.GUID);
}
}
Here is the test code to pick an Element and call the schema-in-and-out method so as to dynamically check the members returned by the Schema.ListSchemas() API helper method:
Reference picked = CachedUiApp.ActiveUIDocument.Selection.PickObject(ObjectType.Element, "Pick a window to attach our data");
SchemaInOut(picked);
If the above test code is put into an external command, Revit is launched, a document is opened, and an Element is picked, we may get something like the following being printed out into the Visual Studio debugger window (the real output depends on what schemas have already been there in the model):
All Schema returned by the Schema.ListSchemas():
da4aae5a-4ee1-45a8-b3e8-f790c84cc44f
Schema 1A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been added.
All Schema returned by the Schema.ListSchemas():
1a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
da4aae5a-4ee1-45a8-b3e8-f790c84cc44f
Schema 2A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been added.
All Schema returned by the Schema.ListSchemas():
1a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
2a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
da4aae5a-4ee1-45a8-b3e8-f790c84cc44f
Schema 1A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been deleted.
All Schema returned by the Schema.ListSchemas():
1a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
2a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
da4aae5a-4ee1-45a8-b3e8-f790c84cc44f
Schema 3A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been added.
All Schema returned by the Schema.ListSchemas():
1a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
2a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
3a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
da4aae5a-4ee1-45a8-b3e8-f790c84cc44f
Schema 3A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been deleted.
All Schema returned by the Schema.ListSchemas():
1a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
2a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
3a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
da4aae5a-4ee1-45a8-b3e8-f790c84cc44f
Schema 2A4AAE5A-4EE1-45A8-B3E8-F790C84CC44F has been deleted.
All Schema returned by the Schema.ListSchemas():
1a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
2a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
3a4aae5a-4ee1-45a8-b3e8-f790c84cc44f
da4aae5a-4ee1-45a8-b3e8-f790c84cc44f
Readers must have noticed that the Schema.ListSchemas() API method only cares about Schema addition. When a new schema is created, the schema list maintained by the API will get it added too. However, it does not care about Schema removal at all. When an existing schema along with its all Entity instances has been removed by the Element.DeleteEntity() call, the API will do nothing about it to its schema list and the Schema.ListSchemas() API method still reports all those schemas that have ever been built in the whole Revit session.
So it would have made more sense if the method were named as ListEverBuiltSchemas() or GetSchemaHistory() or something like that. In terms of at which moment that the new schema will be added to the list is not clear yet. When the SchemaBuilder is constructed, when an Entity is created from the Schema, or when the Entity has been successfully the very first time attached to any Element?
If readers are interested, please go ahead and sort it out yourselves. Based on all the above test code, it should not be a big deal. Another article to address it may be posted out soon. Please stay tuned.
The Revit Addin Wizard (RevitAddinWizard) provides a Revit Data Operator/Extension coder to help generate Extensible Storage code.
Recent Comments