Showing Current Selection in a Modeless Form

Showing Current Selection in a Modeless Form


There is a question post in the AutoCAD .NET discussion forum here. I happened to have a similar requirement in one of my recent development projects. So, instead of post a reply in the discussion forum there, I though it would be easier to post a relatively simple and run-able project for the benefit of all readers.

The project is fairly easy and is comprised of 3 classes.

Class CurrentSelectionWatcher:

using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace ShowSelectionChange
{
    public class CurrentSelectionWatcher
    {
        private frmSelection _view = null;
        private bool _show = false;
        private Document _curDoc = null;
        public CurrentSelectionWatcher()
        {
            _curDoc = CadApp.DocumentManager.MdiActiveDocument;
            if (_curDoc != null)
            {
                SetView();
                _curDoc.ImpliedSelectionChanged += 
                    Document_ImpliedSelectionChanged;
            }

            CadApp.DocumentManager.DocumentBecameCurrent += 
                DocumentManager_DocumentBecameCurrent;
        }

        public bool IsShown
        {
            get { return _show; }
        }

        private void Document_ImpliedSelectionChanged(
            object sender, EventArgs e)
        {
            SetView();
        }
        
        private void DocumentManager_DocumentBecameCurrent(
            object sender, DocumentCollectionEventArgs e)
        {
            if (_curDoc!=null)
            {
                _curDoc.ImpliedSelectionChanged -= 
                    Document_ImpliedSelectionChanged;
            }

            if (e.Document!=null)
            {
                if (e.Document != _curDoc)
                {
                    ClearView();
                    SetView();
                    _curDoc = e.Document;
                    _curDoc.ImpliedSelectionChanged += 
                        Document_ImpliedSelectionChanged;
                }
            }
        }

        public void Show()
        {
            _view = new frmSelection();
            _view.VisibleChanged += _view_VisibleChanged;
            CadApp.ShowModelessDialog(_view);
            _show = true;
        }

        private void _view_VisibleChanged(object sender, EventArgs e)
        {
            if (!_view.Visible)
            {
                _view.Dispose();
                _view = null;
                _show = false;
            }
        }

        #region private methods

        private void ClearView()
        {
            _view.ClearView();
        }

        private void SetView()
        {
            if (!_show) return;
            if (!_curDoc.IsActive) return;
            
            var res = _curDoc.Editor.SelectImplied();
            if (res.Status==PromptStatus.OK)
            {
                _view.SetSelection(res.Value.GetObjectIds());
            }
            else
            {
                _view.ClearView();
            }

        }

        #endregion
    }
}

Then a Windows.Form class frmSelection:



This form contains a ListView, a Button and a Label.

Here is the code-behind:
using System;
using System.Windows.Forms;

using Autodesk.AutoCAD.DatabaseServices;

namespace ShowSelectionChange
{
    public partial class frmSelection : Form
    {
        public frmSelection()
        {
            InitializeComponent();

            ClearView();
        }

        public void ClearView()
        {
            lvSelection.Items.Clear();
            lblCount.Text = "Selected: 0";
        }

        public void SetSelection(ObjectId[] entIds)
        {
            ClearView();

            foreach (var id in entIds)
            {
                var item = new ListViewItem(id.ToString());
                item.SubItems.Add(id.ObjectClass.DxfName);
                item.Selected = false;

                lvSelection.Items.Add(item);           
            }

            lblCount.Text = "Selected: " + 
                lvSelection.Items.Count.ToString();
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Visible = false;
        }
    }
}

And finally, here the the CommandClass that runs the code:
using Autodesk.AutoCAD.Runtime;

[assemblyCommandClass(typeof(ShowSelectionChange.Commands))]

namespace ShowSelectionChange
{
    public class Commands
    {
        private static CurrentSelectionWatcher _selectionCounter = null;

        [CommandMethod("WatchSelection"CommandFlags.Session)]
        public static void DoSessionCommand()
        {
            if (_selectionCounter==null)
            {
                _selectionCounter = new CurrentSelectionWatcher();
            }

            if (!_selectionCounter.IsShown) _selectionCounter.Show();
        }
    }
}

Here is a video clip shows how the code works.

Obviously, I can make the floating form as static and only show/hide it instead of creating new instance/disposing. Of course the modeless form can be substituted by a PaletteSet easily.

P.S. When I copied the code a few hours ago, I missed a couple of lines, which actually makes the execution appear having a bug. The missing lines has been added (in red). I also missed the link to the video clip.

Extra Code

In the following discussion on the topic in AutoCAD .NET API forum, the OP asked if I could show sample code with a PaletteSet. So, here are some extra codee, working in this manner:

  • When only one entity is selected/highlighted, and the entity is a lightweight polyline, a floating PaletteSet with single palette shows the polylines information;
  • When more than one entities are selected, or no entity is selected, the PaletteSet hides automatically.
The codes are as following.

First, I created another selection watching class CurrentSelectionWatcherA.cs:

using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.DatabaseServices;

namespace ShowSelectionChange
{
    public class CurrentSelectionWatcherA
    {
        private MyPolylinePaletteSet _ps = null;
        private Document _curDoc = null;

        public CurrentSelectionWatcherA()
        {
            _ps = new MyPolylinePaletteSet();

            _curDoc = CadApp.DocumentManager.MdiActiveDocument;
            if (_curDoc != null)
            {
                SetView();
                _curDoc.ImpliedSelectionChanged += 
                    Document_ImpliedSelectionChanged;
            }

            CadApp.DocumentManager.DocumentBecameCurrent += 
                DocumentManager_DocumentBecameCurrent;
        }

        private void Document_ImpliedSelectionChanged(
            object sender, EventArgs e)
        {
            SetView();
        }
        
        private void DocumentManager_DocumentBecameCurrent(
            object sender, DocumentCollectionEventArgs e)
        {
            if (_curDoc!=null)
            {
                _curDoc.ImpliedSelectionChanged -= 
                    Document_ImpliedSelectionChanged;
            }

            if (e.Document!=null)
            {
                if (e.Document != _curDoc)
                {
                    SetView();
                    _curDoc = e.Document;
                    _curDoc.ImpliedSelectionChanged += 
                        Document_ImpliedSelectionChanged;
                }
            }
        }

        #region private methods

        private void SetView()
        {
            if (!_curDoc.IsActive)
            {
                _ps.Visible = false;
                return;
            }

            ObjectId polyId = ObjectId.Null;
            var res = _curDoc.Editor.SelectImplied();
            if (res.Status==PromptStatus.OK)
            {
                if (res.Value.Count==1)
                {
                    var id = res.Value[0].ObjectId;
                    if (id.ObjectClass.DxfName.ToUpper()=="LWPOLYLINE")
                    {
                        polyId = id;
                    }
                }            
            }
            
            if (polyId.IsNull)
            {
                _ps.Visible = false;
            }
            else
            {
                _ps.ShowPolyline(polyId);
                _ps.Visible = true;
            }
        }

        #endregion
    }
}

Secondly, here is the PaletteSet class MyPolylinePaletteSet.cs:

using System;
using System.Drawing;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Windows;

namespace ShowSelectionChange
{
    public class MyPolylinePaletteSet : PaletteSet
    {
        private PolylinePalette _palette = null;

        public MyPolylinePaletteSet():
            base("My Polyline","",new Guid("D07DBD90-4D4C-44DB-A6C4-3CC030BD0520"))
        {
            Style = PaletteSetStyles.UsePaletteNameAsTitleForSingle;
            DockEnabled = DockSides.None;
            Dock = DockSides.None;
            Size = new Size(300, 200);
            MinimumSize = new Size(300, 200);

            _palette = new Polyli

visit link download

Popular posts from this blog

Game Online Balap Bus

Smart Phone Upgrade Tool v1 5 3 Full Crack Setup Free Download

Silent Hill 4 Room 303 Key