Issue
I want to attach a property set to an AEC object, using AutoCAD Architecture .NET API. How can we do that?
Solution
PropertyDataServices provides a convenient method to do the job. You can use its method:
PropertyDataServices.AddPropertySet(object, propertySetDefinitionID).
The code below demonstrates the usage. The command asks the user to select an AEC object and to type the name of property set definition, and then attach the given property set to the given object.
' Attach a property set to an object.
' Minimum error checking for code readability.
' In practice, you may want to check if a specific prop set is
' already attached before you are attaching again.
<CommandMethod("ACANetScheduleLabs",
"AcaAttachPropertySet",
CommandFlags.Modal)> _
Public Sub AttachPropertySet()
' Top most objects.
Dim doc As Document =
Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
' (1) select an AEC object to attach a property set
Dim optEnt As New PromptEntityOptions(
vbLf & "Select an AEC object to attach a property set")
optEnt.SetRejectMessage(
vbLf & "Selected entity is NOT an AEC object, try again...")
' "Geo" is the base class for AEC object.
' Use this if you want to apply to all the AEC objects.
optEnt.AddAllowedClass(GetType(Geo), False)
' If you are interested in only Door object, use this instead.
'optEnt.AddAllowedClass(GetType(Door), False)
Dim resEnt As PromptEntityResult = ed.GetEntity(optEnt)
If resEnt.Status <> PromptStatus.OK Then
ed.WriteMessage("Selection error - aborting")
Exit Sub
End If
' We have an object to attach a property set.
Dim idTargetObj As ObjectId = resEnt.ObjectId
' (2) Ask for the name of property set definition to attach.
Dim optStr As New PromptStringOptions(
vbLf +
"Enter the name of property set definition to attach.")
Dim resPropSetDef As PromptResult = ed.GetString(optStr)
If resPropSetDef.Status <> PromptStatus.OK Then
ed.WriteMessage("String input error - aborting")
Exit Sub
End If
' We have the name of property set definition.
Dim propSetDefName As String = resPropSetDef.StringResult
' Find the property set definition with the given name.
Dim dictPropSetDef = New DictionaryPropertySetDefinitions(db)
Dim idPropSetDef As ObjectId =
Utils.findStyle(dictPropSetDef, propSetDefName)
If idPropSetDef = Nothing Then Return
' If we come here, we have a prop set def id and an object id.
' (3) Attach the given property set to the given object.
Try
Using tr As Transaction =
db.TransactionManager.StartTransaction
Dim obj As AcObject =
tr.GetObject(idTargetObj, OpenMode.ForWrite, False, False)
' PropertyDataServices provide a convenient method to do
' the actual work.
PropertyDataServices.AddPropertySet(obj, idPropSetDef)
tr.Commit()
End Using
Catch ex As Exception
ed.WriteMessage(
"error in AttachPropertySet: " + ex.ToString + vbCrLf)
End Try
End Sub
And here is the helper functions, Utils.findStyle() I used in the above code:
Public Class Utils
' Helper function: findStyle().
'
' Find a style (or dictionary record) with the given name
' from the given dictionary, and return its object id.
Public Shared Function findStyle(ByRef dict As AecDb.Dictionary,
ByVal key As String) As ObjectId
Dim doc As Document =
Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
' The id of the style we are looking for. Return value
Dim id As ObjectId = Nothing
Try
Using tr As Transaction =
db.TransactionManager.StartTransaction
' Do we have a property set definition with the given name?
If Not dict.Has(key, tr) Then
' If not, return
ed.WriteMessage("cannot find the style: " + key + vbCrLf)
Return Nothing
End If
tr.Commit()
End Using
' Get the id of property set definition from the name
id = dict.GetAt(key)
Catch ex As Exception
ed.WriteMessage(
"error in findPropertySetDef: " + ex.ToString + vbCrLf)
End Try
Return id
End Function
End Class