AutoCAD has supported the eXtended Data for long time, back to the ADS era. In the AutoCAD .NET world, those functionalities regarding the XData manipulations and even those extended DXF codes are wrapped nicely into some classes, structs, methods and enums.
However, because of the different syntaxes in the new AutoCAD .NET and the old ADS, even for people coming from the ADS time and using those old ResultBuffer a lot, they may still be confused about some classes, methods, and enum values as far as XData and ResultBuffer are concerned.
In this post, let’s delete some XData associated with a picked entity.
[CommandMethod("DeleteXData")]
public static void DeleteXData_Method()
{
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
try
{
PromptEntityResult prEntRes = ed.GetEntity("\nSelect an Entity to delete XDATA from");
if (prEntRes.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Entity ent = (Entity)tr.GetObject(prEntRes.ObjectId, OpenMode.ForRead);
if (ent.XData == null)
{
ed.WriteMessage("\nNo XData in the entity.");
return;
}
string appName = ed.GetString("\nAppName for the XData to delete (Enter for ALL)").StringResult;
if (string.IsNullOrEmpty(appName) && MessageBox.Show("Woult you really like to delete all XData associated with the entity?", "Delete All XData", MessageBoxButtons.YesNo) == DialogResult.No)
return;
if (string.IsNullOrEmpty(appName))
{
foreach (TypedValue tv in ent.XData.AsArray().Where(e => e.TypeCode == 1001))
{
ent.UpgradeOpen();
ent.XData = new ResultBuffer(new TypedValue(1001, tv.Value));
ent.DowngradeOpen();
}
ed.WriteMessage("\nAll XData have been deleted.");
}
else
{
ResultBuffer rb = ent.GetXDataForApplication(appName);
if (rb != null)
{
ent.UpgradeOpen();
ent.XData = new ResultBuffer(new TypedValue(1001, appName));
ent.DowngradeOpen();
ed.WriteMessage("\nXData with AppName {0} have been deleted.", appName);
}
else
ed.WriteMessage("\nIt doesn't have XData with AppName {0}.", appName);
}
tr.Commit();
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
Various scenarios have been covered in the code and command. The code seems simple and straightforward, but there are quite some tips and tricks there.
• The DBObject.GetXDataForApplication() method can retrieve the XData with the specified application name from a DBObject or Entity.
• All XData starts with the 1001 (DxfCode.ExtendedDataRegAppName) code.
• The XData Application Name can be registered through creating a RegAppTableRecord and adding it to the RegAppTable (another kind of AutoCAD symbol table).
• The ResultBuffer is a list of TypedValue which is a pair of type and value.
• To remove the XData with a particular RegAppName from an entity, we have to construct a ResultBuffer having a single TypedValue of a pair of DxfCode as 1001 (DxfCode.ExtendedDataRegAppName) and Value as the same XData Application Name, and assign the ResultBuffer to the Entity.XData.
• Otherwise, the Entity.XData will not be deleted. Instead, their order may be adjusted. It sounds not quite natural, but that is what the real world is.
• The good point is that it can save us some time and effort. We don’t have to check or filter each XData Application Name, or remove the applicable XData item one by one from the ResultBuffer.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides project wizards in C#, VB.NET and CLI/Managed C++, and various item wizards such as Event Handlers, Command/LispFunction Definers, and Entity/Draw Jiggers in both C# and VB.NET, to help program AutoCAD addins.
Posted by: |