After looking at how the Bindable Object Layer (BOL) in AutoCAD might be used to get information about the current drawing, in today’s post we’re going to see how it can also be used to manipulate that data (in a fairly limited, albeit useful, way).
But first, let’s talk a bit about the origins of the BOL. It was first introduced as an architectural feature of AutoCAD when we were looking at delivering AutoCAD for Mac. It’s common, these days, for programming frameworks to provide some kind of data-binding facility to simplify the creation of UIs: both WPF and Cocoa have data-binding capabilities, for instance, that allow programmers to point collection-friendly UI widgets – such as list- and combo-boxes – at core data collections containing the information they wish to present to the user.
The BOL was our (primarily internal) effort to create a cross-platform, abstract information layer that could be bound via WPF on Windows and Cocoa on OS X to present the UI most appropriate to the respective platforms. Some work was needed to expose the core layer on each platform, but the underlying C++ implementation – contained within AcCore – is shared across platforms.
For instance, much of the information regarding the state of the current drawing – such as the current layer, linetype, dimension/table/text/visual (etc.) style – is providing to AutoCAD’s ribbon by the BOL. The BOL provides the most recent information – it gets updated as the drawing changes and even as the active drawing changes – so that the UI can simply update whenever changes propagate through the BOL.
Which actually makes the BOL quite a powerful abstraction for use programmatically, too. While it’s not directly possible to add items to the BOL and have them appear in the drawing, it is possible to use the BOL to change the “current” item in a collection, and also to use the BOL to find out when modifications have been made to its various collections.
The BOL can therefore be used to change the current Visual Style, the current layer, or – as we show in the post – the current named view.
And here’s the C# code that does so:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows.Data;
using System.Collections.Generic;
public class BolAccess
{
[CommandMethod("CHGVW")]
static public void ChangeViewViaBol()
{
Editor ed =
Application.DocumentManager.MdiActiveDocument.Editor;
// Get our set of named views
var views = Application.UIBindings.Collections.NamedViews;
if (views.Count == 0)
{
ed.WriteMessage("\nNo named views available.");
}
else
{
ed.WriteMessage("\nNamed views available:");
// Create a list in which to store the names of our views
List<string> viewNames = new List<string>(views.Count);
// Loop through the view list, populating our list of names
// and printing each one for later selection
for(int i=0; i < views.Count; i++)
{
// Add a dummy item - will be replaced via the index later
viewNames.Add("");
var desc = views[i];
// Get the collection's property descriptors
var props = desc.GetProperties();
// Set our view name as the value of each "Name" property
// (do so by index, just to make sure we're keeping in sync
// with the values in the views collection)
viewNames[i] = (string)props["Name"].GetValue(desc);
// Print the name along with the 1-based index
ed.WriteMessage("\n {0} {1}", i+1, viewNames[i]);
}
// Ask the user to select the view based on the index
PromptIntegerOptions opts =
new PromptIntegerOptions("\nEnter number of view: ");
opts.LowerLimit = 1;
opts.UpperLimit = views.Count;
PromptIntegerResult pir = ed.GetInteger(opts);
if (pir.Status == PromptStatus.OK)
{
// Simply set our current item to the one selected
views.CurrentItem = views[pir.Value - 1];
}
}
}
}
When we run the CHGVW command inside the “visualization_-_condominium_with_skylight.dwg” sample drawing, we see we can use it to navigate easily between the various named views: