使用 .NET API 以正确的方式向模型添加元素 space
Adding elements to model space the correct way using .NET API
方法一
_AcDb.Line oLine = new _AcDb.Line(ptStart, ptEnd);
AddToModelSpace("PLOT", oLine);
其中 AddToModelSpace
是:
public static void AddToModelSpace(string strLayer, _AcDb.Entity oEntity)
{
_AcAp.Document acDoc = _AcAp.Application.DocumentManager.MdiActiveDocument;
_AcDb.Database acCurDb = acDoc.Database;
_AcEd.Editor ed = acDoc.Editor;
using (_AcDb.BlockTable bt = acCurDb.BlockTableId.GetObject(_AcDb.OpenMode.ForRead) as _AcDb.BlockTable)
using (_AcDb.BlockTableRecord ms = bt[_AcDb.BlockTableRecord.ModelSpace].GetObject(_AcDb.OpenMode.ForWrite) as _AcDb.BlockTableRecord)
ms.AppendEntity(oEntity);
oEntity.Layer = strLayer;
oEntity.Dispose();
}
方法二
// Get the current document and database
_AcAp.Document docActive = _AcAp.Application.DocumentManager.MdiActiveDocument;
_AcDb.Database docDB = docActive.Database;
// Start a transaction
using (_AcDb.Transaction acTrans = docDB.TransactionManager.StartTransaction())
{
// Open the Block table for read
_AcDb.BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(docDB.BlockTableId,
_AcDb.OpenMode.ForRead) as _AcDb.BlockTable;
// Open the Block table record Model space for write
_AcDb.BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[_AcDb.BlockTableRecord.ModelSpace],
_AcDb.OpenMode.ForWrite) as _AcDb.BlockTableRecord;
// Create line
using (_AcDb.Line acLine = new _AcDb.Line(ptStart, ptEnd))
{
// Add the new object to the block table record and the transaction
acBlkTblRec.AppendEntity(acLine);
acTrans.AddNewlyCreatedDBObject(acLine, true);
}
// Save the new object to the database
acTrans.Commit();
}
我在我的项目中使用了AddToModelSpace
,希望它没问题!
方法二是Autodesk在开发者文档中推荐的方式(可以阅读this section)。
在方法一中,您使用ObjectId.GetObject()
方法打开BlockTable
和模型space 'BlockTableRecord'。此方法使用顶级事务打开对象,这意味着您应该使用一个活动事务来添加新创建的实体。您可以使用 Database.TransactionManager.TopTransaction
获取它。如果你根本不想使用事务,你必须使用 "for advanced use only" ObjectId.Open()
方法。
方法三应该使用一些从事务中调用的扩展方法。这是我使用的简化(非错误检查)摘录。
static class ExtensionMethods
{
public static T GetObject<T>(
this ObjectId id,
OpenMode mode = OpenMode.ForRead,
bool openErased = false,
bool forceOpenOnLockedLayer = false)
where T : DBObject
{
return (T)id.GetObject(mode, openErased, forceOpenOnLockedLayer);
}
public static BlockTableRecord GetModelSpace(this Database db, OpenMode mode = OpenMode.ForRead)
{
return SymbolUtilityServices.GetBlockModelSpaceId(db).GetObject<BlockTableRecord>(mode);
}
public static ObjectId Add (this BlockTableRecord owner, Entity entity)
{
var tr = owner.Database.TransactionManager.TopTransaction;
var id = owner.AppendEntity(entity);
tr.AddNewlyCreatedDBObject(entity, true);
return id;
}
}
使用示例:
using (var tr = db.TransactionManager.StartTransaction())
{
var line = new Line(startPt, endPt) { Layer = layerName };
db.GetModelSpace(OpenMode.ForWrite).Add(line);
tr.Commit();
}
方法一
_AcDb.Line oLine = new _AcDb.Line(ptStart, ptEnd);
AddToModelSpace("PLOT", oLine);
其中 AddToModelSpace
是:
public static void AddToModelSpace(string strLayer, _AcDb.Entity oEntity)
{
_AcAp.Document acDoc = _AcAp.Application.DocumentManager.MdiActiveDocument;
_AcDb.Database acCurDb = acDoc.Database;
_AcEd.Editor ed = acDoc.Editor;
using (_AcDb.BlockTable bt = acCurDb.BlockTableId.GetObject(_AcDb.OpenMode.ForRead) as _AcDb.BlockTable)
using (_AcDb.BlockTableRecord ms = bt[_AcDb.BlockTableRecord.ModelSpace].GetObject(_AcDb.OpenMode.ForWrite) as _AcDb.BlockTableRecord)
ms.AppendEntity(oEntity);
oEntity.Layer = strLayer;
oEntity.Dispose();
}
方法二
// Get the current document and database
_AcAp.Document docActive = _AcAp.Application.DocumentManager.MdiActiveDocument;
_AcDb.Database docDB = docActive.Database;
// Start a transaction
using (_AcDb.Transaction acTrans = docDB.TransactionManager.StartTransaction())
{
// Open the Block table for read
_AcDb.BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(docDB.BlockTableId,
_AcDb.OpenMode.ForRead) as _AcDb.BlockTable;
// Open the Block table record Model space for write
_AcDb.BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[_AcDb.BlockTableRecord.ModelSpace],
_AcDb.OpenMode.ForWrite) as _AcDb.BlockTableRecord;
// Create line
using (_AcDb.Line acLine = new _AcDb.Line(ptStart, ptEnd))
{
// Add the new object to the block table record and the transaction
acBlkTblRec.AppendEntity(acLine);
acTrans.AddNewlyCreatedDBObject(acLine, true);
}
// Save the new object to the database
acTrans.Commit();
}
我在我的项目中使用了AddToModelSpace
,希望它没问题!
方法二是Autodesk在开发者文档中推荐的方式(可以阅读this section)。
在方法一中,您使用ObjectId.GetObject()
方法打开BlockTable
和模型space 'BlockTableRecord'。此方法使用顶级事务打开对象,这意味着您应该使用一个活动事务来添加新创建的实体。您可以使用 Database.TransactionManager.TopTransaction
获取它。如果你根本不想使用事务,你必须使用 "for advanced use only" ObjectId.Open()
方法。
方法三应该使用一些从事务中调用的扩展方法。这是我使用的简化(非错误检查)摘录。
static class ExtensionMethods
{
public static T GetObject<T>(
this ObjectId id,
OpenMode mode = OpenMode.ForRead,
bool openErased = false,
bool forceOpenOnLockedLayer = false)
where T : DBObject
{
return (T)id.GetObject(mode, openErased, forceOpenOnLockedLayer);
}
public static BlockTableRecord GetModelSpace(this Database db, OpenMode mode = OpenMode.ForRead)
{
return SymbolUtilityServices.GetBlockModelSpaceId(db).GetObject<BlockTableRecord>(mode);
}
public static ObjectId Add (this BlockTableRecord owner, Entity entity)
{
var tr = owner.Database.TransactionManager.TopTransaction;
var id = owner.AppendEntity(entity);
tr.AddNewlyCreatedDBObject(entity, true);
return id;
}
}
使用示例:
using (var tr = db.TransactionManager.StartTransaction())
{
var line = new Line(startPt, endPt) { Layer = layerName };
db.GetModelSpace(OpenMode.ForWrite).Add(line);
tr.Commit();
}