December 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 31      










« Delete “all but current” Annotation Scales on AutoCAD objects using .NET | Main | Using the Microsoft Kinect SDK to model 3D polylines inside AutoCAD »

October 07, 2011

Displaying an AutoCAD ribbon tab contextually using .NET

This very interesting feature came to my attention via an internal discussion. Thanks, once again, to George Varghese for providing the base sample used for this post.

At various times inside AutoCAD – such as when a block is selected, for instance – a specific ribbon tab is displayed “contextually”. As an example, when you select a Hatch object inside the AutoCAD editor, you should see a hatch-related contextual tab displayed:

Hatch editor contextual tab

It’s possible to implement your own, comparable behaviour inside the AutoCAD editor using a combination of a simple .NET module, a XAML file and some CUI editing (or a partial CUI file).

Let’s start with the .NET module. Here’s some code that implements a sample rule that can be hooked into AutoCAD to tell it when a certain condition has been satisfied. In our case, the condition we want is that exactly two circles are selected in the drawing editor.

Here’s the C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using System;

 

namespace Rules

{

  public class SampleRule

  {

    // The flag stating whether the contextual tab is enabled

 

    bool _enableCtxtTab = false;

 

    // A static reference to the rule itself

 

    static SampleRule _rule = null;

 

    // A public property referenced from the XAML, getting

    // whether the contextual tab should be enabled

 

    public bool TwoCirclesSelected

    {

      get { return _enableCtxtTab; }

    }

 

    // A public static property providing access to the rule

    // (also referenced from the XAML)

 

    public static SampleRule TheRule

    {

      get

      {

        if (_rule == null)

          _rule = new SampleRule();

 

        return _rule;

      }

    }

 

    // Constructor for the rule, where we attach various

    // even handlers

 

    SampleRule()

    {

      DocumentCollection dm =

        Autodesk.AutoCAD.ApplicationServices.Application.

        DocumentManager;

 

      dm.DocumentCreated +=

        new DocumentCollectionEventHandler(

          OnDocumentCreated

        );

      dm.DocumentToBeDestroyed +=

        new DocumentCollectionEventHandler(

          OnDocumentToBeDestroyed

        );

      dm.MdiActiveDocument.ImpliedSelectionChanged +=

        new EventHandler(

          OnImpliedSelectionChanged

        );

    }

 

    // When the pickfirst selection is changed, check

    // the selection to see whether to enable the

    // contextual tab (if exactly two circles are selected)

 

    void OnImpliedSelectionChanged(object sender, EventArgs e)

    {

      Editor ed =

        Application.DocumentManager.MdiActiveDocument.Editor;

      PromptSelectionResult res = ed.SelectImplied();

      if (res == null)

        return;

 

      EnableContextualTab(res.Value);

    }

 

    // When a document is created, add our handler to it

 

    void OnDocumentCreated(

      object sender, DocumentCollectionEventArgs e

    )

    {

      e.Document.ImpliedSelectionChanged +=

        new EventHandler(OnImpliedSelectionChanged);

    }

 

    // When a document is destroyed, remove our handler from it

 

    void OnDocumentToBeDestroyed(

      object sender, DocumentCollectionEventArgs e

    )

    {

      e.Document.ImpliedSelectionChanged -=

        new EventHandler(OnImpliedSelectionChanged);

    }

 

    // Check whether we should enable the contextual tab,

    // based on the selection passed in

 

    void EnableContextualTab(SelectionSet ss)

    {

      // The default assumption is "no"

 

      _enableCtxtTab = false;

 

      // We need to have exactly two objects selected

 

      if (ss == null)

        return;

 

      if (ss.Count == 2)

      {

        ObjectId[] ids = ss.GetObjectIds();

        if (ids != null)

        {

          Database db =

            HostApplicationServices.WorkingDatabase;

          Transaction tr =

            db.TransactionManager.StartTransaction();

          using (tr)

          {

            // Check whether both objects are Circles

 

            DBObject obj =

              tr.GetObject(ids[0], OpenMode.ForRead);

            DBObject obj2 =

              tr.GetObject(ids[1], OpenMode.ForRead);

 

            _enableCtxtTab = (obj is Circle && obj2 is Circle);

 

            // Commit, as it's quicker than aborting

 

            tr.Commit();

          }

        }

      }

    }

  }

}

The above code is reasonably simple – it detects changes to the pickfirst selection set and checks whether it contains exactly two objects, both of which are circles. If so, it sets a Boolean property that can be checked by AutoCAD.

To tell AutoCAD what to do with the module, we need to include a small XAML file which AutoCAD will parse on startup:

<?xml version="1.0" encoding="utf-8"?>

<TabSelectorRules

  xmlns="clr-namespace:Autodesk.AutoCAD.Ribbon;assembly=AcWindows"

  Ordering="0">

  <TabSelectorRules.References>

    <AssemblyReference

      Namespace="Rules"

      Assembly="ADNPlugin-SampleRule"/>

  </TabSelectorRules.References>

  <Rule

    Uid="ADNPluginSampleRuleId"

    DisplayName="Sample: Two circles selected rule"

    Theme="Green"

    Trigger="Selection">

    <![CDATA[

      SampleRule.TheRule.TwoCirclesSelected

    ]]>

  </Rule>

</TabSelectorRules>

The DLL and XAML files are to be placed in the AutoCAD executable folder (on my system this is “C:\Program Files\Autodesk\AutoCAD 2012 - English”), which means it’s imperative you prefix both with your Registered Developer Symbol (RDS), obtainable from http://autodesk.com/symbolreg.

In my case – as I have the ADNP symbol registered – I’ve named the files ADNPlugin-SampleRule.dll and  ADNPlugin-SampleContextualTabSelectorRules.xaml. You can find them here, along with the source project.

Now on to actually using the rule inside AutoCAD.

Launch AutoCAD: if all is well you should see nothing out of the ordinary, otherwise you’ll see lots of additional (and often very helpful) text describing the problem with your rule implementation (or its XAML description).

Run the CUI command. From here you should see a new node named “Sample: Two circles selected rule” under Ribbon –> Contextual Tab States.

Our new Contextual Tab State in the CUI dialog

To have a custom tab displayed when this condition is true, simply drag and drop the tab from the Ribbon –> Tabs list to our new node. You’ll see a number of tabs named “… Contextual Tab”, for just this purpose. Just for fun – and because we can – let’s show the “Solid Modeling” tab when two circles are selected in the editor.

Let's show the solid modelling tab when two circles are selected

Sure enough, when we close the CUI dialog, saving changes, and select two circles in the AutoCAD editor, we see the Solid Modeling tab gets displayed and highlighted with our chosen theme (a green tint to it):

The Solid Modeling tab displayed contextually when two circles are selected

Now of course it’s unlikely you’ll want to do something quite like this, but this sample does show how you might implement your own contextual tabs, and not just for objects of a certain – you can perform quite deep analysis of the selection set, should you so wish (keeping an eye on interactive performance, of course).

blog comments powered by Disqus

Feed/Share

10 Random Posts