You can use extended data (xdata) as a means for linking information with objects in a drawing.
This example prompts the user to select objects from the drawing. The selected objects are placed into a selection set, and the specified xdata is attached to all objects in that selection set.
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
<CommandMethod("AttachXDataToSelectionSetObjects")> _
Public Sub AttachXDataToSelectionSetObjects()
' Get the current database and start a transaction
Dim acCurDb As Autodesk.AutoCAD.DatabaseServices.Database
acCurDb = Application.DocumentManager.MdiActiveDocument.Database
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim appName As String = "MY_APP"
Dim xdataStr As String = "This is some xdata"
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
' Request objects to be selected in the drawing area
Dim acSSPrompt As PromptSelectionResult = acDoc.Editor.GetSelection()
' If the prompt status is OK, objects were selected
If acSSPrompt.Status = PromptStatus.OK Then
' Open the Registered Applications table for read
Dim acRegAppTbl As RegAppTable
acRegAppTbl = acTrans.GetObject(acCurDb.RegAppTableId, OpenMode.ForRead)
' Check to see if the Registered Applications table record for the custom app exists
Dim acRegAppTblRec As RegAppTableRecord
If acRegAppTbl.Has(appName) = False Then
acRegAppTblRec = New RegAppTableRecord
acRegAppTblRec.Name = appName
acTrans.GetObject(acCurDb.RegAppTableId, OpenMode.ForWrite)
acRegAppTbl.Add(acRegAppTblRec)
acTrans.AddNewlyCreatedDBObject(acRegAppTblRec, True)
End If
' Define the Xdata to add to each selected object
Using rb As New ResultBuffer
rb.Add(New TypedValue(DxfCode.ExtendedDataRegAppName, appName))
rb.Add(New TypedValue(DxfCode.ExtendedDataAsciiString, xdataStr))
Dim acSSet As SelectionSet = acSSPrompt.Value
' Step through the objects in the selection set
For Each acSSObj As SelectedObject In acSSet
' Open the selected object for write
Dim acEnt As Entity = acTrans.GetObject(acSSObj.ObjectId, _
OpenMode.ForWrite)
' Append the extended data to each object
acEnt.XData = rb
Next
End Using
End If
' Save the new object to the database
acTrans.Commit()
' Dispose of the transaction
End Using
End Sub
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
[CommandMethod("AttachXDataToSelectionSetObjects")]
public void AttachXDataToSelectionSetObjects()
{
// Get the current database and start a transaction
Database acCurDb;
acCurDb = Application.DocumentManager.MdiActiveDocument.Database;
Document acDoc = Application.DocumentManager.MdiActiveDocument;
string appName = "MY_APP";
string xdataStr = "This is some xdata";
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Request objects to be selected in the drawing area
PromptSelectionResult acSSPrompt = acDoc.Editor.GetSelection();
// If the prompt status is OK, objects were selected
if (acSSPrompt.Status == PromptStatus.OK)
{
// Open the Registered Applications table for read
RegAppTable acRegAppTbl;
acRegAppTbl = acTrans.GetObject(acCurDb.RegAppTableId, OpenMode.ForRead) as RegAppTable;
// Check to see if the Registered Applications table record for the custom app exists
if (acRegAppTbl.Has(appName) == false)
{
using (RegAppTableRecord acRegAppTblRec = new RegAppTableRecord())
{
acRegAppTblRec.Name = appName;
acTrans.GetObject(acCurDb.RegAppTableId, OpenMode.ForWrite);
acRegAppTbl.Add(acRegAppTblRec);
acTrans.AddNewlyCreatedDBObject(acRegAppTblRec, true);
}
}
// Define the Xdata to add to each selected object
using (ResultBuffer rb = new ResultBuffer())
{
rb.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName));
rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, xdataStr));
SelectionSet acSSet = acSSPrompt.Value;
// Step through the objects in the selection set
foreach (SelectedObject acSSObj in acSSet)
{
// Open the selected object for write
Entity acEnt = acTrans.GetObject(acSSObj.ObjectId,
OpenMode.ForWrite) as Entity;
// Append the extended data to each object
acEnt.XData = rb;
}
}
}
// Save the new object to the database
acTrans.Commit();
// Dispose of the transaction
}
}
Sub AttachXDataToSelectionSetObjects()
' Create the selection set
Dim sset As Object
Set sset = ThisDrawing.SelectionSets.Add("SS1")
' Prompt the user to select objects
sset.SelectOnScreen
' Define the xdata
Dim appName As String, xdataStr As String
appName = "MY_APP"
xdataStr = "This is some xdata"
Dim xdataType(0 To 1) As Integer
Dim xdata(0 To 1) As Variant
' Define the values for each array
' 1001 indicates the appName
xdataType(0) = 1001
xdata(0) = appName
' 1000 indicates a string value
xdataType(1) = 1000
xdata(1) = xdataStr
' Loop through all entities in the selection
' set and assign the xdata to each entity
Dim ent As Object
For Each ent In sset
ent.SetXData xdataType, xdata
Next ent
End Sub
This example displays the xdata attached with the previous example. If you attach xdata other than strings (type 1000), you will need to revise this code.
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
<CommandMethod("ViewXData")> _
Public Sub ViewXData()
' Get the current database and start a transaction
Dim acCurDb As Autodesk.AutoCAD.DatabaseServices.Database
acCurDb = Application.DocumentManager.MdiActiveDocument.Database
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim appName As String = "MY_APP"
Dim msgstr As String = ""
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
' Request objects to be selected in the drawing area
Dim acSSPrompt As PromptSelectionResult = acDoc.Editor.GetSelection()
' If the prompt status is OK, objects were selected
If acSSPrompt.Status = PromptStatus.OK Then
Dim acSSet As SelectionSet = acSSPrompt.Value
' Step through the objects in the selection set
For Each acSSObj As SelectedObject In acSSet
' Open the selected object for read
Dim acEnt As Entity = acTrans.GetObject(acSSObj.ObjectId, _
OpenMode.ForRead)
' Get the extended data attached to each object for MY_APP
Dim rb As ResultBuffer = acEnt.GetXDataForApplication(appName)
' Make sure the Xdata is not empty
If Not IsNothing(rb) Then
' Get the values in the xdata
For Each typeVal As TypedValue In rb
msgstr = msgstr & vbCrLf & typeVal.TypeCode.ToString() & ":" & typeVal.Value
Next
Else
msgstr = "NONE"
End If
' Display the values returned
MsgBox(appName & " xdata on " & VarType(acEnt).ToString() & ":" & vbCrLf & msgstr)
msgstr = ""
Next
End If
' Ends the transaction and ensures any changes made are ignored
acTrans.Abort()
' Dispose of the transaction
End Using
End Sub
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
[CommandMethod("ViewXData")]
public void ViewXData()
{
// Get the current database and start a transaction
Database acCurDb;
acCurDb = Application.DocumentManager.MdiActiveDocument.Database;
Document acDoc = Application.DocumentManager.MdiActiveDocument;
string appName = "MY_APP";
string msgstr = "";
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Request objects to be selected in the drawing area
PromptSelectionResult acSSPrompt = acDoc.Editor.GetSelection();
// If the prompt status is OK, objects were selected
if (acSSPrompt.Status == PromptStatus.OK)
{
SelectionSet acSSet = acSSPrompt.Value;
// Step through the objects in the selection set
foreach (SelectedObject acSSObj in acSSet)
{
// Open the selected object for read
Entity acEnt = acTrans.GetObject(acSSObj.ObjectId,
OpenMode.ForRead) as Entity;
// Get the extended data attached to each object for MY_APP
ResultBuffer rb = acEnt.GetXDataForApplication(appName);
// Make sure the Xdata is not empty
if (rb != null)
{
// Get the values in the xdata
foreach (TypedValue typeVal in rb)
{
msgstr = msgstr + "\n" + typeVal.TypeCode.ToString() + ":" + typeVal.Value;
}
}
else
{
msgstr = "NONE";
}
// Display the values returned
Application.ShowAlertDialog(appName + " xdata on " + acEnt.GetType().ToString() + ":\n" + msgstr);
msgstr = "";
}
}
// Ends the transaction and ensures any changes made are ignored
acTrans.Abort();
// Dispose of the transaction
}
}
Sub ViewXData()
' Find the selection created in previous example
Dim sset As Object
Set sset = ThisDrawing.SelectionSets.Item("SS1")
' Define the xdata variables to hold xdata information
Dim xdataType As Variant
Dim xdata As Variant
Dim xd As Variant
' Define index counter
Dim xdi As Integer
xdi = 0
' Loop through the objects in the selection set
' and retrieve the xdata for the object
Dim msgstr As String
Dim appName As String
Dim ent As AcadEntity
appName = "MY_APP"
For Each ent In sset
msgstr = ""
xdi = 0
' Retrieve the appName xdata type and value
ent.GetXData appName, xdataType, xdata
' If the xdataType variable is not initialized, there
' was no appName xdata to retrieve for that entity
If VarType(xdataType) <> vbEmpty Then
For Each xd In xdata
msgstr = msgstr & vbCrLf & xdataType(xdi) & ": " & xd
xdi = xdi + 1
Next xd
End If
' If the msgstr variable is NULL, there was no xdata
If msgstr = "" Then msgstr = vbCrLf & "NONE"
MsgBox appName & " xdata on " & ent.ObjectName & ":" & vbCrLf & msgstr
Next ent
End Sub