November 2014

Sun Mon Tue Wed Thu Fri Sat
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            










« .NET Reflector Pro discount | Main | API wishlist surveys for Autodesk products »

May 07, 2010

Populating a tree view inside AutoCAD with sheet set data using .NET

A big thank you to Fenton Webb, from DevTech Americas, for providing the code which was the basis for this post. Thanks, Fents! :-)

Fenton sent a version of this code recently to an ADN member who was interested in duplicating the information shown in AutoCAD’s Sheet Set Manager inside a custom, palette-hosted tree-view dialog. Fenton’s version made use of WPF: I’ve dumbed it down a little to use WinForms, but may do a follow-up post using WPF (although the WPF TreeView doesn’t appear to support data-binding, so I may well decide not to bother).

I have made some other changes to Fenton’s code, and if there are any bugs they’re likely to be mine rather than his. I fleshed out some of the various item types, but as I haven’t yet been able to see them in action (I’m not even sure there was any real need to do so), they may need some further work or even stripping out.

Anyway, here’s the C# code. To make it work your project will need a reference to acsmcomponents18.tlb (or acsmcomponents17.tlb if using AutoCAD 2007-2009) as well as AcMgd.dll, AcDbMgd.dll and the standard .NET components that Visual Studio may be looking for when building the project.

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.Windows;

using acApp =

  Autodesk.AutoCAD.ApplicationServices;

using ACSMCOMPONENTS18Lib;

using System.Windows.Forms;

using System;

 

namespace MyApplication

{

  public class Commands

  {

    static PaletteSet ps = null;

    static UserControl1 userControl = null;

 

    [CommandMethod("SSTREE")]

    public void PopulateCustomSheetTree()

    {

      // Check the state of the paletteset

 

      if (ps == null)

      {

        // Then create it

 

        ps = new PaletteSet("Custom Sheet Tree");

        userControl = new UserControl1();

        ps.Add("MySheetView", userControl);

      }

 

      ps.Visible = true;

 

      // Get the AutoCAD Editor

 

      Editor ed =

        acApp.Application.DocumentManager.MdiActiveDocument.Editor;

 

      // Get the SheetSet Manager

 

      AcSmSheetSetMgr mgr = new AcSmSheetSetMgr();

 

      // Create a new SheetSet Database

 

      AcSmDatabase db = new AcSmDatabase();

 

      // Try and load a default DST file...

 

      try

      {

        db =

          mgr.OpenDatabase(

            @"C:\Program Files\Autodesk\AutoCAD 2011\Sample\" +

            @"Sheet Sets\Architectural\IRD Addition.dst",

            true

          );

      }

      catch (System.Exception ex)

      {

        ed.WriteMessage(ex.ToString());

        return;

      }

 

      // Lock the db for processing

 

      db.LockDb(db);

 

      AcSmSheetSet ss = db.GetSheetSet();

 

      // Create a root item in the TreeView,

      // the name of the SheetSet

 

      TreeNode root = new TreeNode(ss.GetName());

      userControl.treeView1.Nodes.Add(root);

 

      ProcessEnumerator(ss.GetSheetEnumerator(), root);

 

      db.UnlockDb(db, true);

      mgr.Close(db);

    }

 

    void ProcessEnumerator(IAcSmEnumComponent iter, TreeNode root)

    {

      IAcSmComponent item = iter.Next();

      while (item != null)

      {

        string type = item.GetTypeName();

        switch (type)

        {

          case "AcSmSubset":

            try

            {

              AcSmSubset subset = (AcSmSubset)item;

              string subName = subset.GetName();

 

              if (!String.IsNullOrEmpty(subName))

              {

                TreeNode tn = AddTreeNode(root, subName);

                IAcSmEnumComponent enumerator =

                  (IAcSmEnumComponent)subset.GetSheetEnumerator();

                ProcessEnumerator(enumerator, tn);

              }

            }

            catch { }

            break;

 

          case "AcSmSheet":

            try

            {

              AcSmSheet sh = (AcSmSheet)item;

              string shName = sh.GetName();

 

              if (!String.IsNullOrEmpty(shName))

              {

                TreeNode tn = AddTreeNode(root, shName);

                IAcSmEnumComponent enumerator =

                  (IAcSmEnumComponent)sh.GetSheetViews();

                ProcessEnumerator(enumerator, tn);

              }

            }

            catch { }

            break;

 

          case "AcSmSheetViews":

            try

            {

              AcSmSheet sh = (AcSmSheet)item;

              string shName = sh.GetName();

 

              if (!String.IsNullOrEmpty(shName))

              {

                TreeNode tn = AddTreeNode(root, shName);

                IAcSmEnumComponent enumerator =

                  (IAcSmEnumComponent)sh.GetSheetViews();

                ProcessEnumerator(enumerator, tn);

              }

            }

            catch { }

            break;

 

          case "AcSmSheetView":

            try

            {

              AcSmSheetView sv = (AcSmSheetView)item;

              string svName = sv.GetName();

 

              if (!String.IsNullOrEmpty(svName))

                AddTreeNode(root, svName);

            }

            catch { }

            break;

 

          case "AcSmCustomPropertyValue":

            AcSmCustomPropertyValue pv =

              (AcSmCustomPropertyValue)item;

 

            AddTreeNode(

              root,

              "Custom property value: " + pv.GetValue().ToString()

            );

            break;

 

          case "AcSmObjectReference":

            AcSmObjectReference or =

              (AcSmObjectReference)item;

 

            AddTreeNode(

              root,

              "Object reference: " +

              or.GetReferencedObject().GetTypeName()

            );

            break;

 

          case "AcSmCustomPropertyBag":

            try

            {

              AcSmCustomPropertyBag bag =

                (AcSmCustomPropertyBag)item;

 

              TreeNode tn = AddTreeNode(root, "Custom property bag");

              IAcSmEnumComponent enumerator =

                (IAcSmEnumComponent)bag.GetPropertyEnumerator();

              ProcessEnumerator(enumerator, tn);

            }

            catch { }

            break;

 

          case "AcSmAcDbLayoutReference":

            AcSmAcDbLayoutReference lr =

              (AcSmAcDbLayoutReference)item;

 

            AddTreeNode(

              root,

              "Layout reference: " + lr.GetName()

            );

            break;

 

          case "AcSmFileReference":

            AcSmFileReference fr = (AcSmFileReference)item;

 

            AddTreeNode(

              root,

              "Layout reference: " + fr.GetFileName()

            );

            break;

 

          case "AcSmAcDbViewReference":

            AcSmAcDbViewReference vr = (AcSmAcDbViewReference)item;

 

            AddTreeNode(

              root,

              "View reference: " + vr.GetName()

            );

            break;

 

          case "AcSmResources":

            try

            {

              AcSmResources res = (AcSmResources)item;

 

              TreeNode tn = AddTreeNode(root, "Resources");

              IAcSmEnumComponent enumerator =

                (IAcSmEnumComponent)res.GetEnumerator();

              ProcessEnumerator(enumerator, tn);

            }

            catch { }

            break;

 

          default:

            Document doc =

              acApp.Application.DocumentManager.MdiActiveDocument;

            Editor ed = doc.Editor;

            ed.WriteMessage("\nMissed Type = " + type);

            break;

        }

        item = iter.Next();

      }

    }

 

    private TreeNode AddTreeNode(TreeNode root, string name)

    {

      // Create a new node on the tree view

 

      TreeNode node = new TreeNode(name);

 

      // Add it to what we have

 

      root.Nodes.Add(node);

      return node;

    }

  }

}

You’ll need to add a new UserControl to your project and a TreeView to that, setting the Dock property to fill. Be sure to keep the default names as UserControl1 and treeView1. Other than than, no UI work is needed.

Here’s what happens when we run the SSTREE command along and load the hard-coded DST file into the SheetSet Manager (displayed with the SSM command) for comparison:

 

Custom Sheet Tree vs. Sheet Set Manager

Clearly more could be done to make the UI look the same (icons, etc.), but this post is more about recursively parsing a SheetSet’s tree rather than anything else. If you come across any issues as you try this out with other data stored in DST files, be sure to post a comment.

blog comments powered by Disqus

Feed/Share

10 Random Posts