Code Red > .NET

Select on layer .. ensure thawed layer

(1/1)

kdub_nz:
Anyone care to break this.

Select objects on a specific layer. Ensure the layer is Thawed.
Sample Drawing attached.

Comments welcome.

added: EDIT Code style changes as per Gilles comments.


--- Code - C#: ---// (C) Codehimbelonga kdub 2019-07-14 //using System;using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.DatabaseServices;using Autodesk.AutoCAD.EditorInput;using Autodesk.AutoCAD.Geometry;using Autodesk.AutoCAD.Runtime;using cadApp = Autodesk.AutoCAD.ApplicationServices.Application;  [assembly: CommandClass(typeof(Test190714.MyCommands))] namespace Test190714{    public class MyCommands    {        [CommandMethod("Doit", CommandFlags.Modal)]        public void MyCommand()        {            var layerName = "Cabling";             var isLayerThawed = FreezeLayer(layerName, freeze: false);            SelectionSet selectedLines;             if (isLayerThawed) {                selectedLines = GrabLines(layerName);            } else {                Active.WriteMessage($"Layer '{layerName}' is not accessable");                return;            }             if (selectedLines != null && selectedLines.Count > 0) {                OutputLineData(selectedLines);            } else {                Active.WriteMessage("Nothing to report");            }        }         /// <summary>Freezes the layer.</summary>        /// <param name="layerName">Name of the layer.</param>        /// <param name="freeze">if set to <c>true</c> [freeze].</param>        /// <returns></returns>        private bool FreezeLayer(string layerName, bool freeze)        {            using (var tr = Active.Database.TransactionManager.StartTransaction()) {                var layerTable = (LayerTable)tr.GetObject(Active.Database.LayerTableId,                                  OpenMode.ForRead);                 if (!layerTable.Has(layerName)) {                    // No Layer, So can't be frozen or thawed                    return false;                }                 var layerRecord = (LayerTableRecord)tr.GetObject(layerTable[layerName],                                   OpenMode.ForWrite);                 if (layerRecord.Id != Active.Database.Clayer) {                    layerRecord.IsFrozen = freeze;                }                tr.Commit();                Active.Editor.Regen();            }            return true;        }         /// <summary>Grabs the lines.</summary>        /// <param name="layerName">Name of the layer.</param>        /// <returns></returns>        public SelectionSet GrabLines(string layerName)        {            TypedValue[] filterValues = new[] {                new TypedValue((int)DxfCode.Start, "LINE"),                new TypedValue((int)DxfCode.LayerName, layerName)            };            var selectionFilter = new SelectionFilter(filterValues);            var selectionOptions = new PromptSelectionOptions {                MessageForAdding = $"Select Lines on Layer {layerName}",                AllowDuplicates = true            };            var selectionResult = Active.Editor.GetSelection(selectionOptions, selectionFilter);             if (!(selectionResult.Status == PromptStatus.OK)) {                return null;            }             return selectionResult.Value;        }          /// <summary>Outputs the line data.</summary>        /// <param name="ss">The ss.</param>        private void OutputLineData(SelectionSet ss)        {            ObjectId[] idarray = ss.GetObjectIds();            using (Transaction tr = Active.Database.TransactionManager.StartTransaction()) {                foreach (var id in idarray) {                    var line = (Line)tr.GetObject(id, OpenMode.ForRead, true);                    Active.WriteMessage(                        $"\nYou selected: {line.GetType().Name} with Length = {line.Length }");                }            }        }    }     /// <summary>    /// Provides easy access to several "active" objects in the     /// AutoCAD runtime environment.    /// Thanks to : Scott McFarlane - Programming AutoCAD with C#: Best Practices    /// </summary>    public static class Active    {        public static Document Document => cadApp.DocumentManager.MdiActiveDocument;        public static Database Database => Document.Database;        public static Editor Editor => Document.Editor;         public static void WriteMessage(            string message)            => Editor.WriteMessage(message);         public static void WriteMessage(            string message, params object[] parameter)            => Editor.WriteMessage(message, parameter);    }}  

gile:
Hi,

Nice code Kerry.
Just 2 things about coding style:


--- Code - C#: ---if (layerTable.Has(layerName) == false)reminds me of the verbose VB style.
You'd never write:
--- Code - C#: ---if (layerTable.Has(layerName) == true) so why not simply write:
--- Code - C#: ---if (!layerTable.Has(layerName))

--- Code - C#: ---            using (Transaction tr = Active.Database.TransactionManager.StartTransaction()) {                try {                    foreach (var id in idarray) {                        var line = (Line)tr.GetObject(id, OpenMode.ForRead, true);                        Active.WriteMessage(                            $"\nYou selected: {line.GetType().Name} with Length = {line.Length }");                    }                }                finally {                    tr.Dispose();                }            } It seems to me the finally block is useless.
The using statement will take care of disposing of the transaction even if an exception occured. So, as you neither have a catch block, the try{...} also is useless.

kdub_nz:
Yes, you are correct :)

Thanks for the scan Gilles


Edit: Code revised as commented.

kdub_nz:
@gile
I liked your option of using an OpenCloseTransaction with this :


--- Code - C#: ---                     var layer = (LayerTableRecord)tr.GetObject(layerTable["Cabling"], OpenMode.ForRead);                    if (layer.IsFrozen)                    {                        layer.UpgradeOpen();                        layer.IsFrozen = false;                    } 
Very clean !

gile:
Thanks Kerry.
Clean, this is the way I try to write.

Navigation

[0] Message Index

Go to full version