在2012之前的版本,二次开发者可以通过Shared Parameter来存储自己的数据。但是有许多不便之处。比如你只希望对某几个对象添加扩展数据,但是shared parameter 确向同一个类别的对象都添加了新的参数。
在2012的api中开放了扩展存储的API,大家可以只对一个具体对象存储数据。可以自定义存储结构,可以存储多个不同类型的数据。需要自己定义存储的schema。而且可以对存储的数据进行访问权限设置,以防别人修改你的数据。
下面是一段代码应用扩展存储 Extensible Storage
#region Namespaces using System; using System.Diagnostics; using System.Collections.Generic; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.ExtensibleStorage; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; #endregion // Namespaces namespace ExtensibleStorage { [Transaction( TransactionMode.Manual )] public class Command : IExternalCommand { static string PluralSuffix( int n ) { return 1 == n ? "" : "s"; } /// <summary> /// Create a data structure, attach it to a wall, /// populate it with data, and retrieve the data /// back from the wall /// </summary> void StoreDataInWall( Wall wall, XYZ dataToStore ) { Transaction createSchemaAndStoreData = new Transaction( wall.Document, "tCreateAndStore" ); createSchemaAndStoreData.Start(); SchemaBuilder schemaBuilder = new SchemaBuilder( new Guid( "720080CB-DA99-40DC-9415-E53F280AA1F1" ) ); // allow anyone to read the object schemaBuilder.SetReadAccessLevel( AccessLevel.Public ); // restrict writing to this vendor only //schemaBuilder.SetWriteAccessLevel( // AccessLevel.Vendor ); //joe changed schemaBuilder.SetWriteAccessLevel( AccessLevel.Public ); // required because of restricted write-access schemaBuilder.SetVendorId( "ADNP" ); // create a field to store an XYZ FieldBuilder fieldBuilder = schemaBuilder .AddSimpleField( "WireSpliceLocation", typeof( XYZ ) ); fieldBuilder.SetUnitType( UnitType.UT_Length ); fieldBuilder.SetDocumentation( "A stored " + "location value representing a wiring " + "splice in a wall." ); schemaBuilder.SetSchemaName( "WireSpliceLocation" ); // register the schema Schema schema = schemaBuilder.Finish(); // create an entity (object) for this schema (class) Entity entity = new Entity( schema ); // get the field from the schema Field fieldSpliceLocation = schema.GetField( "WireSpliceLocation" ); // set the value for this entity entity.Set<XYZ>( fieldSpliceLocation, dataToStore, DisplayUnitType.DUT_METERS ); // store the entity on the element wall.SetEntity( entity ); createSchemaAndStoreData.Commit(); // read back the data from the wall Entity retrievedEntity = wall.GetEntity( schema ); XYZ retrievedData = retrievedEntity.Get<XYZ>( schema.GetField( "WireSpliceLocation" ), DisplayUnitType.DUT_METERS ); } /// <summary> /// List all schemas in Revit memory across all documents. /// </summary> void ListSchemas() { IList<Schema> schemas = Schema.ListSchemas(); int n = schemas.Count; Debug.Print( string.Format( "{0} schema{1} defined:", n, PluralSuffix( n ) ) ); foreach( Schema s in schemas ) { IList<Field> fields = s.ListFields(); n = fields.Count; Debug.Print( string.Format( "Schema '{0}' has {1} field{2}:", s.SchemaName, n, PluralSuffix( n ) ) ); foreach( Field f in fields ) { Debug.Print( string.Format( "Field '{0}' has value type {1} and unit type {2}", f.FieldName, f.ValueType, f.UnitType ) ); } } } class WallFilter : ISelectionFilter { public bool AllowElement( Element e ) { return e is Wall; } public bool AllowReference( Reference r, XYZ p ) { return true; } } public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements ) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Document doc = uidoc.Document; try { // pick an element and define the XYZ // data to store at the same time Reference r = uidoc.Selection.PickObject( ObjectType.Face, new WallFilter(), "Please pick a wall at a point on one of its faces" ); Wall wall = doc.get_Element( r.ElementId ) as Wall; XYZ dataToStore = r.GlobalPoint; // store the data, and also // demonstrate reading it back StoreDataInWall( wall, dataToStore ); // list all schemas in memory across all documents ListSchemas(); return Result.Succeeded; } catch( Exception ex ) { message = ex.Message; return Result.Failed; } } } }