Some time ago, I posted code that used the Autodesk.AutoCAD.Windows.Data namespace to list the hatch patterns in the current drawing.
Fenton Webb posted a follow-up on the AutoCAD DevBlog that took this further, extracting additional data from AutoCAD and using it to populate an Excel spreadsheet. Within that post, Fenton showed the technique required to access and iterate across other data collections – something I hadn’t managed to do when creating my original post.
Rather than repeat exactly what Fenton has put together – which is really nice, do take a look at it – I’m just taking a small amount of Fenton’s code and replicating it here – along with some code using reflection, to keep the code succinct – to dump some data to the command-line:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows.Data;
public class DataStuff
{
[CommandMethod("HPS")]
static public void GetHatchPatterns()
{
Editor ed =
Application.DocumentManager.MdiActiveDocument.Editor;
foreach (
string str in HatchPatterns.Instance.AllPatterns)
ed.WriteMessage("\n" + str);
}
[CommandMethod("DUMPBOL")]
static public void DumpBindableObjects()
{
Editor ed =
Application.DocumentManager.MdiActiveDocument.Editor;
// Get our set of collections
var cols = Application.UIBindings.Collections;
// Use reflection to determine the properties of type
// DataItemCollection (could extend to support others, too)
var t = cols.GetType();
var tprops = t.GetProperties();
foreach (var tprop in tprops)
{
// Make sure we only deal with DataItemCollection properties
// that do not take any parameters
if (
tprop.PropertyType == typeof(DataItemCollection) &&
tprop.GetGetMethod().GetParameters().Length == 0
)
{
// Dump our the property name first
ed.WriteMessage("\n{0}:", tprop.Name);
// Get the collection itself and iterate through it
var col = (DataItemCollection)tprop.GetValue(cols, null);
foreach (var desc in col)
{
// Get the collection's property descriptors
var props = desc.GetProperties();
try
{
// Dump the value of each "Name" property
ed.WriteMessage(
" \"{0}\"", props["Name"].GetValue(desc)
);
}
catch
{
// Just in case no "Name" property exists, we try-catch
}
}
}
}
}
}
The main trick is actually to get data from the BOL – AutoCAD’s Bindable Object Layer – via the various properties inside Application.UIBindings.Collections.
We’re using reflection to avoid hardcoding the various properties we want to access: we just loop through the main collection set’s properties, looking for any of type DataItemCollection. We might also extend the code to support other property types – such as EnumItemCollection – but that’s left as an exercise for the reader.
Here’s the command-line output we see in a blank drawing when we run the DUMPBOL command:
Command: DUMPBOL
UcsPlanes:
PlotStyles:
RenderPresets: "" "" "" "" ""
TableCellStyles:
NamedViews:
Linetypes: "ByBlock" "ByLayer" "Continuous" "PHANTOM2"
LayerFilters: "All" "All Used Layers" "Unreconciled New Layers" "Viewport Overrides"
LayerStates:
Layers: "0"
VisualStyles: "2D Wireframe" "Conceptual" "Hidden" "Realistic" "Shaded" "Shaded with edges" "Shades of Gray" "Sketchy" "Wireframe" "X-Ray"
TextStyles: "Standard" "Annotative"
DimensionStyles: "Standard" "Annotative"
DetailViewStyles: "Imperial24"
SectionViewStyles: "Imperial24"
MleaderStyles: "Annotative" "Standard"
TableStyles: "Standard"