按特殊层擦除对象
我已经很久没有用C#写任何东西了,所以我发布这篇文章是为了看看我是否犯了一些明显的错误。代码工作正常(如果需要,我可以提供调用的帮助函数),并且我能够打开保存的绘图,并且没有错误。唯一缺少的是,当在编辑器中打开图形时,项目会被删除,但图形不会刷新。单击图形后,重新生成会解决问题。预先感谢, 公共类EraseClouds。{。
。
public void erase cloud()。
{。
欧特克,AutoCAD . windows . openfile dialog dia = new Autodesk,AutoCAD . windows . openfile dialog(。
“选择要删除实体的图形,”,""," dwg "," tmwCloudErase ",。
欧特克,AutoCAD . windows . openfile dialog . openfile dialog flags . allow multiple 。
);。
如果(直径,ShowDialog()!=对话结果,OK)退货;。
文档cdoc = Autodesk,AutoCAD . application services . application . document manager . mdiactivedocument;。
数据库cdb = cdoc,数据库;。
string[] files = dia,get filenames();。
文档doc。
DocumentLock dlock。
数据库db;。
BlockTable bt。
BlockTableRecord btr。
实体输入;。
层表lt,。
LayerTableRecord ltr。
bool didErase。
foreach(文件中的字符串名称){。
didErase = false。
db = MyUtility,GetDatabaseAtPath(名称,cdb,文件共享。Read,FindFileHint。XRefDrawing,out doc);。
if (db == null)继续;。
if (doc!= null) dlock = doc,lock document();。
使用(Transaction trans = db,transaction manager . start transaction()){ 。
bt = trans,GetObject(db,BlockTableId,OpenMode。ForRead,false,true)作为BlockTable。
foreach(Bt中的ObjectId id){ 。
btr = trans,GetObject(id,OpenMode。ForRead,false,true)作为BlockTableRecord。
foreach(btr中的ObjectId oid){ 。
ent = trans,GetObject(oid,OpenMode。ForRead,false,true)作为实体;。
if(字符串,比较(ent,Layer,0," Cloud-",0,6,true) == 0 ) {。
ent,upgrade open();。
ent,erase();。
ent,degrade open();。
didErase = true。
}。
}。
}。
lt = trans,GetObject(db,LayerTableId,OpenMode。ForRead,false,true)作为LayerTable。
foreach(lt中的ObjectId id){ 。
ltr = trans,GetObject(id,OpenMode。ForRead,false,true)作为LayerTableRecord。
if(字符串,比较(ltr,名字,0,“云——”,0,6,真)!= 0)继续;。
ltr,upgrade open();。
ltr,erase();。
ltr,degrade open();。
didErase = true。
}。
运输,commit();。
}。
if (doc == null) {。
if (didErase){。
dbSaveAs(name,true,DwgVersion。电流,db。security参数);。
cdoc,Editor.WriteMessage("\n已从:"+ name "中删除云实体);。
}。
dbdispose();//这是因为helper函数。
}。
else {。
if (didErase)。
cdoc,Editor.WriteMessage("\n从打开的图形中删除云实体:"+name ");。
}。
}。
}。
}。
。
**** Hidden Message ***** 如果你想要的只是重生,你可以扔一个cdoc。editor . Regen();在事务提交之后。 if (doc != null) dlock = doc.LockDocument();您应该将其放在嵌套在事务语句上方的“using”语句中,主要是因为它在完成后解锁文档并正确处置。using (DocumentLock dlock = doc.LockDocument())。
使用 (事务事务 trans = db.TransactionManager.StartTransaction()) {是的,你可以使用这样的语句嵌套,如果你想省略它们,就不需要嵌套的大括号。。
当你说"...绘图已在编辑器中打开..."您是指在该过程之后,您在AutoCAD中打开图形,还是指由于该过程,图形已经在AutoCAD中打开,并且在编辑器中显示/看到的图形直到您单击编辑器时才更新(通常,您只能对最后一个处理并保持打开的图形执行此操作)?在我看来是后一种情况,但是不太确定,因为db = MyUtility的方法签名非常奇怪。GetDatabaseAtPath([文件名],[当前文件],...,...out )
此函数是否用于返回当前打开文档的数据库的一个辅助数据库?函数的签名没有给出它将返回哪一个(或者,如果out Doucment为null,那么返回的数据库是side DB?).从命令标志来看。会话中,似乎该功能实际上在AutoCAD中打开了文件名列表中的每个图形。如果是这样,最好让函数简单地返回文档,并且它的数据库也可以通过文档访问。数据库属性
现在,如果每个图形都在AutoCAD中打开,则每个图形在AutoCAD中打开时都会由于命令标记而变成MdiActiveDocument。会话,您可以简单地调用编辑器。在每个绘图过程结束时更新Screen()。你只需要调用编辑器。Regen()用于显示某些更改,如更新字段、应用否决...
在我看来,对于代码执行的任务,使用side database可以更快地完成,而不是在AutoCAD editor中打开每一个。 阿图克:我会考虑尝试这个。 由于返回的文档可能不是活动文档,因此我不确定它是否有效。 我会在尝试后报告。 谢谢。
CADbloke:我没有对锁定过程使用“using”语句,因为它可能并不总是适用。 仅当图形在当前会话中被当前用户打开时,才需要锁定图形。 在这种情况下,我可以确保销毁锁,就像我创建数据库一样。 谢谢。
n.yuan:当代码启动时,如果当前用户未在编辑器中打开绘图,程序将使用侧数据库来完成任务。 这就是传递文档的原因,以便在用户执行代码时碰巧打开文档时可以锁定该文档。 谢谢。
我将尝试建议的更新并报告回来。 因此,看起来您只能重新生成活动文档,因此,如果从具有图层的文档启动该命令,它将更新,但是如果擦除当前未打开的图形(在编辑器中)中的图层,则 regen 调用将不执行任何操作。
我已经看到,在对在编辑器中打开但不是最新的图形进行操作时,我通常使用“using”语句,因此,如果锁定对象不为空,则我在锁定对象上实现了 Destroy 方法。
谢谢大家。 它似乎工作没有错误或损坏图纸。 如果你说的是删除图层时的界面更新,试着打开图层表进行写操作。我想那会导致UI更新。
您可能还想尝试TransactionManager。QueueForGraphicsFlush();在提交事务之前。 杰夫·H:当我试着这样做时,编辑器中打开的图形(不是当前的)没有刷新显示
Atook:“TransactionManager。QueueForGraphicsFlush();'导致错误“eNotFromThisDrawing”(我认为我的错误是正确的)
这不是什么大问题,因为现在只有我在使用代码。谢谢你的尝试,非常感谢。
页:
[1]