Bernd 发表于 2020-2-7 07:42:46

Solved - eInvalidInput in AttributeReference.SetAttributeFromBlock() in BricsCAD

我正在尝试将一个AutoCAD应用程序移植到BricsCAD,大多数开箱即用就能正常工作,但我正在努力使用一种方法来绘制带有属性的块。在AutoCAD中,此代码片段工作正常:   使用(var modelSpace = (AcadDbServices。BlockTableRecord)trans,GetObject(block table,AcadDbServices。OpenMode.ForWrite))。
使用(var block definition =(acadbservices,BlockTableRecord)trans,GetObject(blockTable,AcadDbServices。OpenMode.ForRead))。
{。
如果(!块定义,HasAttributeDefinitions)。
createblockdefinitionwith Attributes(trans,block,attributes。钥匙);。

使用(var block reference = new acaddb services,BlockReference(位置,块定义。ObjectId))。
{。
模型空间,append entity(block reference);。
运输,AddNewlyCreatedDBObject(block reference,true);。

块引用,ScaleFactors =新AcadGeometry,scale 3d(FAK tor);。
块引用,旋转= drehung。
块引用,层=层;。

foreach (AcadDbServices,blockDefinition中的ObjectId oid)。
{。
var attributeDefinition = trans,GetObject(oid,AcadDbServices。OpenMode.ForRead)作为AcadDbServices,属性定义;。
if(attribute definition = = null | | attribute definition,常数)。
继续;。

使用(var attribute reference = new AcadDbServices,AttributeReference())。
{。
/*下一行因eInvalidInput */而崩溃。
属性引用,SetAttributeFromBlock(attribute definition,blockReference。block transform);。
属性引用,TextString = attributes;。

块引用,attribute collection . AppendAttribute(attribute reference);。
运输,AddNewlyCreatedDBObject(attribute reference,true);。
}。
}。
}。
运输,commit();。
}。
    CreateBlockDefinitionWithAttributes()是这样定义的:   私有静态void CreateBlockDefinitionWithAttributes(AcadDbServices,事务trans,字符串blockName,IEnumerable属性)。
{。
AcadDbServices,数据库dwg = AcadDbServices,HostApplicationServices . working database;。

尝试一下。
{。
if(字符串,IsNullOrEmpty(blockName))。
throw new argument exception(" block name darf nicht leer sein ");。

使用(var blockTable = (AcadDbServices,块表)trans,GetObject(dwg。块表Id,AcadDbServices。OpenMode.ForWrite))。
使用(var block definition =(acadbservices,BlockTableRecord)trans,GetObject(block table,AcadDbServices。OpenMode.ForWrite))。
{。
foreach(属性中的var属性)。
{。
使用(var attribute definition = new AcadDbServices,AttributeDefinition())。
{。
属性定义,标签=属性;。
属性定义,可见=假;。

块定义,AppendEntity(attribute definition);。
运输,AddNewlyCreatedDBObject(attribute definition,true);。
}。
}。
}。
}。
catch(异常e)。
{。
/*做点什么*/。
}。
}。
在BricsCAD中,第28行attributeReference中的代码崩溃。SetAttributeFromBlock(attribute definition,blockReference。block transform);知道这可能是什么原因吗?谢谢,贝恩德。
**** Hidden Message *****

owenwengerd 发表于 2020-2-7 18:18:59

如果在SetAttributeFromBlock()之前附加Attribute()会有帮助吗?或者尝试在SetAttributeFromBlock()之前调用SetDatabaseDefaults()。

Bernd 发表于 2020-2-10 02:12:33

不,不幸的是没有。既没有把blockReference.AttributeCollection.AppendAttribute放在attributeReference.SetAttributeFromBlock前面,也没有调用SetDataBaseDefaault()来阻止代码崩溃。

MickD 发表于 2020-2-10 02:34:56

使用(var attribute definition = new AcadDbServices,attribute definition())//db会照顾这个ref吗??。
只是在这里大声思考,但可能attributeDefinition指针(引用)在添加到db之前被释放(在每个循环的末尾)?或者也许您需要在修改它之前将这个def添加到db(在内部事务中提交它)?。

Bernd 发表于 2020-2-10 06:03:49

但是它不应该通过trans添加到db中吗?AddNewlyCreatedDbObject()?尽管如此,还是试了一下:    if(!块定义。HasAttributeDefinitions)。
{。
var innerTransaction = dwg,transaction manager . start transaction();。
createblockdefinitionwith Attributes(inner transaction,block,attributes。钥匙);。
}。
然后在CreateBlockDefinitionWithAttributes()中:   ...。
foreach(属性中的var属性)。
{。
使用(var attribute definition = new AcadDbServices,AttributeDefinition())。
{。
属性定义,标签=属性;。
属性定义,可见=假;。

块定义,AppendEntity(attribute definition);。
运输,AddNewlyCreatedDBObject(attribute definition,true);。
}。
}。

运输,commit();。
...。
但在调用CreateBlockDefinitionWithAttributes()之前,仍然是相同的旧eInvalidInput,我有两个ActiveTransactions,之后又有一个是预期的,我了解到BricsCAD对待通过封闭事务对象打开的对象的方式不同于AutoCAD **,但我认为这不应该适用于此,应该吗?**我的意思是:在事务结束后访问DBObject:在AutoCAD中,属于某个事务的对象在某些情况下甚至在事务结束后仍然可以访问,在BricsCAD中,当事务结束时,所有事务驻留对象都被关闭。

Bernd 发表于 2020-2-10 07:05:49

我认为:
using (var attributeDefinition = new AcadDbServices.AttributeDefinition())
{
    attributeDefinition.Tag = attribute;
    attributeDefinition.Visible = false;
    blockDefinition.AppendEntity(attributeDefinition);
    trans.AddNewlyCreatedDBObject(attributeDefinition, true);
}

应该是这样的:
using (var attributeDefinition = new AcadDbServices.AttributeDefinition())
{
    blockDefinition.AppendEntity(attributeDefinition);
    trans.AddNewlyCreatedDBObject(attributeDefinition, true);
    attributeDefinition.Tag = attribute;
    attributeDefinition.Visible = false;
}

MickD 发表于 2020-2-10 07:14:46

使用应该很好,交易不会再次处置该物品
此外,您还可以缓存对象ID,以便在事务外部使用。如果您只需要打开进行读取,那么使用openclose事务会更快
或objectid。在using语句中打开()

Bernd 发表于 2020-2-10 07:21:46

仅供参考,Teigha有点无情,创建DB对象后立即使用设置数据库默认值或将其添加到数据库是一个很好的习惯

n.yuan 发表于 2020-2-10 10:30:03

翻译错误代码(429):请求 QPS 超过限制。

Bernd 发表于 2020-2-10 18:26:22

私有静态字典_bloecke;//块名到块路径,例如"myBlock","C:\temp\myBlock.dwg"。
私有静态字符串_searchPath;//包含块(图纸)的目录。

内部静态字符串GibPfadZuBlock(字符串块名称)。
{。
尝试。
{。
如果String.IsNullOrEmpty(_searchPath)
页: [1] 2
查看完整版本: Solved - eInvalidInput in AttributeReference.SetAttributeFromBlock() in BricsCAD