.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Entity Context Menus

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
BrentBurgess1980
918 Views, 2 Replies

Entity Context Menus

I am trying to attach a context menu for unloading an xref when it is selected. (more for curiosity than anything else)

 

Below is the code I have, which I modified from Kean Walmsley's Post

 

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Windows

Namespace ContextMenuApplication
    Public Class Commands
        Implements IExtensionApplication


        Public Sub Initialize() Implements IExtensionApplication.Initialize
            XrefMenu.Attach()
        End Sub

        Public Sub Terminate() Implements IExtensionApplication.Terminate
            XrefMenu.Detach()
        End Sub

    End Class

    Public Class XrefMenu
        Private Shared cme As ContextMenuExtension

        Public Shared Sub Attach()
            cme = New ContextMenuExtension()
            Dim mi As New MenuItem("Unload Xref")
            AddHandler mi.Click, AddressOf UnloadXrefs
            cme.MenuItems.Add(mi)
            Dim rxc As RXClass = Entity.GetClass(GetType(XrefGraphNode))
            Application.AddObjectContextMenuExtension(rxc, cme)
        End Sub

        Public Shared Sub Detach()
            Dim rxc As RXClass = Entity.GetClass(GetType(XrefGraphNode))
            Application.RemoveObjectContextMenuExtension(rxc, cme)
        End Sub

        Private Shared Sub UnloadXrefs(ByVal sender As Object, ByVal e As EventArgs)
            ''Unload Xrefs
        End Sub

    End Class

End Namespace

 

 

I can't seem to figure out the RXClass required to which I attach the menu. Does anyone have an idea of the RXClass required?

 

Thanks

 

Brent

2 REPLIES 2
Message 2 of 3

Hi Brent,

Hopefully some other brilliant person will come back and prove me wrong, but I don't think you're going to be able to pull this one off.  An Xref selected in the drawing window would be treated as a BlockReference by AutoCAD.  It just has a Flag (in the BlockTableRecord) that says it is Externally Dependant, so I don't see a way to attach a context menu to just Xref's, without having that menu apply to all BlockReferences.

Dave O.                                                                  Sig-Logos32.png
Message 3 of 3

As the other reply points out, you need to specify the RXClass on BlockReference type. Thus, the entity context menu items you created will always available, be it the selected entity is a Blockreference or a Xref.

 

One solution is to do futher "filtering" on the entity type in the ContextMenuExtension.PopUp event handler. That is, in this event handler, you can test current selected entity (it must be Blockreference, in this case) to if its BlockTablerecord is a Xref/Overlay or not (BlockTableRecord.IsFromExternalReference/IsFromOverlayReference property). and then enable Xref specific menu items accordingly.

 

I have some code in C#:

 

using System;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Windows;

namespace ConfigEntContextMenu
{
    public class XrefContextMenu
    {
        private ContextMenuExtension _ctMenu = null;
        private static XrefContextMenu _instance = null;

        public static XrefContextMenu Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new XrefContextMenu();
                }

                return _instance;
            }
        }

        public void AttachMenu()
        {
            if (_ctMenu != null) _ctMenu.Dispose();

            _ctMenu = new ContextMenuExtension();

            MenuItem mi = new MenuItem("Bind Xref");
            _ctMenu.MenuItems.Add(mi);
            mi.Click +=new EventHandler(Bind_Click);

            mi = new MenuItem("Unload Xref");
            _ctMenu.MenuItems.Add(mi);
            mi.Click += new EventHandler(Unload_Click);

            mi = new MenuItem("Detach Xref");
            _ctMenu.MenuItems.Add(mi);
            mi.Click += new EventHandler(Detach_Click);

            _ctMenu.Popup +=new EventHandler(XrefContextMenu_Popup);

            RXClass rx = RXClass.GetClass(typeof(BlockReference));
            Application.AddObjectContextMenuExtension(rx, _ctMenu);
        }

        #region private methods

        private void Bind_Click(object sender, EventArgs e)
        {
            Application.ShowAlertDialog("Binding selected XRef");
        }

        private void Unload_Click(object sender, EventArgs e)
        {
            Application.ShowAlertDialog("Unloading selected XRef");
        }

        private void Detach_Click(object sender, EventArgs e)
        {
            Application.ShowAlertDialog("Detaching selected XRef");
        }

        private void XrefContextMenu_Popup(object sender, EventArgs e)
        {
            Document dwg = Application.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;

            bool enable = false;

            PromptSelectionResult res = ed.SelectImplied();
            if (res.Status == PromptStatus.OK)
            {
                if (res.Value.Count == 1)
                {
                    if (IsXref(res.Value.GetObjectIds()[0], dwg))
                    {
                        enable = true;
                    }
                }
            }

            foreach (MenuItem mi in _ctMenu.MenuItems)
            {
                mi.Enabled = enable;
            }
        }

        private bool IsXref(ObjectId id, Document dwg)
        {
            bool isX = false;

            using (Transaction tran = 
                dwg.Database.TransactionManager.StartTransaction())
            {
                BlockReference bref = 
                    tran.GetObject(id, OpenMode.ForRead) as BlockReference;

                if (bref != null)
                {
                    BlockTableRecord br = 
                        (BlockTableRecord)tran.GetObject(bref.BlockTableRecord, 
                        OpenMode.ForRead);
                    if (br.IsFromExternalReference || br.IsFromOverlayReference)
                    {
                        isX = true;
                    }
                }

                tran.Commit();
            }

            return isX;
        }

        #endregion
    }
}

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;

[assembly: CommandClass(typeof(ConfigEntContextMenu.MyCommands))]
[assembly: ExtensionApplication(typeof(ConfigEntContextMenu.MyCommands))]

namespace ConfigEntContextMenu
{
    public class MyCommands : IExtensionApplication
    {
        #region IExtensionApplication Members

        public void Initialize()
        {
            Document dwg = Application.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;

            try
            {
                ed.WriteMessage("\nCreate Xref context menu...");
                XrefContextMenu.Instance.AttachMenu();

                ed.WriteMessage("...done\n");
            }
            catch(System.Exception ex)
            {
                ed.WriteMessage("...failed");
                ed.WriteMessage("\nError: {0}\n", ex.Message);
            }
        }

        public void Terminate()
        {

        }

        #endregion

        #region private methods

       

        #endregion
    }
}

 Open a drawing with a few blocks inserted and a few Xref attached. You can see the 3 custom context menu items are enabled when right-clicking on Xrefs and disbaled when right-clicking on blocks.

 

Norman Yuan

Drive CAD With Code

EESignature

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost