Autocad .NET 将属性添加到块定义

Autocad .NET add attribute to block definition

我正在尝试编写属性 'injection' 工具 - 也就是说,它会提示您输入属性的名称,点插入它,然后将其插入到块定义中(不仅仅是参考),然后同步本地块参考。

这是我得到的:

<CommandMethod("INJECTOR", CommandFlags.Session)>
Sub Injector()
    Dim doc As Document = DocumentManager.MdiActiveDocument
    Dim ed As Editor = doc.Editor
    Dim acdb As Database = doc.Database
    Dim opts As New PromptEntityOptions(vbNewLine & "Select Block:")
    Dim res As PromptEntityResult = ed.GetEntity(opts)
    If res.Status <> PromptStatus.OK Then Exit Sub
    Dim id As ObjectId = res.ObjectId
    Using doc.LockDocument
        Using tr As Transaction = doc.Database.TransactionManager.StartTransaction
            Dim blk As BlockReference = tr.GetObject(id, OpenMode.ForRead)
            Dim blkName As String = blk.Name.ToUpper()
            Dim bt As BlockTable = tr.GetObject(acdb.BlockTableId, OpenMode.ForRead)
            Dim btr As BlockTableRecord = tr.GetObject(bt(blkName), OpenMode.ForWrite)
            If btr.Name.ToUpper() = blkName Then
                btr.UpgradeOpen()
                Dim brefIds As ObjectIdCollection = btr.GetBlockReferenceIds(False, True)
                Dim stropts As New PromptStringOptions(vbNewLine & "Attribute Name:")
                Dim strres As PromptResult = ed.GetString(stropts)
                If strres.Status <> PromptStatus.OK OrElse strres.StringResult = "CANCEL" Then Exit Sub
                Dim attName As String = strres.StringResult
                Dim posopts As New PromptPointOptions(vbNewLine & "Select Point:")
                Dim pntres As PromptPointResult = ed.GetPoint(posopts)
                If pntres.Status <> PromptStatus.OK Then Exit Sub
                Dim pnt3d As New Point3d(pntres.Value.X - blk.Position.X, pntres.Value.Y - blk.Position.Y, pntres.Value.Z - blk.Position.Z)
                ed.WriteMessage(vbNewLine & "Adding attribute called " & attName & " at " & pnt3d.X & "," & pnt3d.Y & "," & pnt3d.Z)
                Dim attDef As New AttributeDefinition()
                attDef.Position = pnt3d
                attDef.AlignmentPoint = pnt3d
                attDef.Verifiable = True
                attDef.Tag = attName
                attDef.Justify = AttachmentPoint.MiddleCenter

                attDef.Invisible = True
                attDef.Height = 3
                btr.AppendEntity(attDef)
                tr.AddNewlyCreatedDBObject(attDef, True)

                Dim circ As New Circle()
                circ.Center = pnt3d
                circ.Radius = 2
                btr.AppendEntity(circ)
                tr.AddNewlyCreatedDBObject(circ, True)

                btr.DowngradeOpen()
                ed.WriteMessage(vbNewLine & "Updating existing block references.")
                For Each objid As ObjectId In brefIds
                    Dim bref As BlockReference = tr.GetObject(objid, OpenMode.ForWrite, False, True)
                    bref.RecordGraphicsModified(True)
                Next
            End If
            tr.Commit()
        End Using
    End Using
End Sub

我不知道为什么这不起作用,它很乐意在属性应该所在的点周围插入圆圈,但属性没有出现,即使在块编辑器中也是如此。

我错过了什么?

P.S。如果您愿意,我可以在 C# 中互换工作!

没错,修好了。基本上我并没有真正理解 AttributeDefinition 的机制:

  1. 出于某种原因,您必须设置 attDef.Invisible 而不是 attDef.Visible。为什么两者都存在我不知道。

  2. 我遇到了一个问题,它似乎总是插入块的原点,但我发现你还必须设置 attDef.Alignment 点。

  3. 最后,我的RecordGraphicsModified方法没有同步属性,我还没有完全解决这个问题。

编辑:如果有人想知道属性同步的事情,我在这里使用了 Gilles Chanteau 的解决方案:https://forums.autodesk.com/t5/net/attsync-in-vb-net/td-p/4645057