在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;
}
}
}
}