cad.net 图层解锁时图层褪色度设置LayLockFadectl

说明

cad交互操作的时候,想跟cad的锁定和解锁一样拥有褪色度,那么你需要阅读此篇

代码

#if !HC2020
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Acap = Autodesk.AutoCAD.ApplicationServices.Application;
#else
using GrxCAD.DatabaseServices;
using GrxCAD.EditorInput;
using GrxCAD.Runtime;
using Acap =  GrxCAD.ApplicationServices.Application;
#endif
using System;

namespace JoinBox
{
    public class 选择图元设置图层褪色度
    {
        [CommandMethod("JJCmd_lock1")]
        public void JJCmd_lock1()
        {
            var dm = Acap.DocumentManager;
            var doc = dm.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var pr = ed.GetEntity("\n请选择图元:锁定");
            if (pr.Status != PromptStatus.OK)
                return;
            db.Action(tr => {
                var getEnt = pr.ObjectId.ToEntity(tr);
                getEnt.LayerLock(true, tr);
            });
        }

        [CommandMethod("JJCmd_lock2")]
        public void JJCmd_lock2()
        {
            var dm = Acap.DocumentManager;
            var doc = dm.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var peo1 = new PromptEntityOptions("\n请选择图元:解锁")
            {
                AllowObjectOnLockedLayer = true,
                AllowNone                = true
            };
            var pr = ed.GetEntity(peo1);
            if (pr.Status != PromptStatus.OK)
                return;
            db.Action(tr => {
                var getEnt = pr.ObjectId.ToEntity(tr);
                getEnt.LayerLock(false, tr);
            });
        }
    }
}

namespace JoinBox
{
    public static partial class LayerHelper
    {
        /// <summary>
        /// 按图元锁定或解锁图层
        /// </summary>
        /// <param name="ent">图元实体</param>
        /// <param name="locked"><see langword="true"/>锁定,<see langword="false"/>解锁</param>
        /// <returns>原本状态</returns>
        public static bool LayerLock(this Entity ent, bool locked, Transaction tr)
        {
            return LayerLock(locked, ent.LayerId, tr, ent.Database);
        }

        /// <summary>
        /// 按层名锁定或解锁图层
        /// </summary>
        /// <param name="locked"><see langword="true"/>锁定,<see langword="false"/>解锁</param>
        /// <param name="layerId">图层</param>
        /// <param name="tr">事务</param>
        /// <param name="db">数据库</param>
        /// <returns>图层原本锁定的状态</returns>
        public static bool LayerLock(bool locked, ObjectId layerId, Transaction tr, Database db)
        {
            if (locked)
            {
                //锁定图层:
                //先遍历这个图层的图元,把它放入刷新队列,因为图层锁了的话图元就无法更改了
                SetLayLockFadectl(true, layerId, tr, db);
            }

            bool oldSetting = false;
            var ltr = tr.GetObject(layerId, OpenMode.ForRead) as LayerTableRecord;
            if (ltr != null)
            {
                ltr.UpgradeOpen();
                oldSetting = ltr.IsLocked;//原本的状态
                ltr.IsLocked = locked;
                ltr.IsOff = ltr.IsOff; //必须设置一下才能更新显示
                ltr.DowngradeOpen();
                ltr.Dispose();
            }

            if (!locked)
            {
                //解锁图层:
                //上面先解锁,再处理褪色度显示,因为图层锁了的话图元就无法更改了
                SetLayLockFadectl(false, layerId, tr, db);
            }
            return oldSetting;
        }

        /// <summary>
        /// 设置图层褪色度显示
        /// </summary>
        /// <param name="locked"><see langword="true"/>锁定,<see langword="false"/>解锁</param>
        /// <param name="layerId">图层</param>
        /// <param name="tr">事务</param>
        /// <param name="db">数据库</param>
        static void SetLayLockFadectl(bool locked, ObjectId layerId, Transaction tr, Database db)
        {
            const string str = "LayLockFadectl";
            var value = int.Parse(CadSystem.Getvar(str));
            value = Math.Abs(value);//锁定-绝对值褪色...设置了会自动刷新屏幕显示
            if (!locked)
                value *= -1;//解锁-负数...设置完之后要手动刷新
            CadSystem.Setvar(str, value.ToString());

            //方案一:获取屏幕内的图元...成功是成功,但是不在屏幕内的褪色度没有变化
            //var ids = ed.SelectViewportObjectId();
            //if (ids == null)
            //    return;
            //ids.ToEntity(tr, entItem => {
            //    entItem.EntityRedraw(BrightEntity.RecordGraphicsModified);
            //});

            //方案二:这个刷新不成功...博客搜:动画
            //ed.UpdateScreenEx();

            //方案三:遍历全图,过滤指定图层图元...
            //这个TraverseEntitys函数在:
            //https://www.cnblogs.com/JJBox/p/12196287.html
            //BrightEntity.RecordGraphicsModified在:
            //https://gitee.com/inspirefunction/ifoxcad/blob/v0.7/src/CAD/IFox.CAD.Shared/ExtensionMethod/RedrawEx.cs

            db.TraverseEntitys(tr, entItem => {
                if (entItem.LayerId == layerId)
                    entItem.EntityRedraw(BrightEntity.RecordGraphicsModified);
                return false;
            });

            //解锁图层之后,有其他图层是锁定的,那么此时需要还原褪色度
            if (!locked)
                CadSystem.Setvar(str, (value * -1).ToString());
        }


    }
}

public static class EditorHelper
{
    /// <summary>
    /// 获取当前屏幕的所有图元
    /// </summary>
    /// <param name="ed"></param>
    /// <param name="tr"></param>
    /// <returns></returns>
    public static ObjectId[] SelectViewportObjectId(this Editor ed)
    {
        var view = ed.GetCurrentView();
        var cpt = view.CenterPoint;
        var w = view.Width / 2;
        var h = view.Height / 2;
      
        var min = new Point3d(cpt.X - w, cpt.Y - h, 0);
        var max = new Point3d(cpt.X + w, cpt.Y + h, 0);
        var ssget = ed.SelectCrossingWindow(min, max);
        if (ssget.Status != PromptStatus.OK)
            return null;
        return ssget.Value.GetObjectIds();
    }
}

特别说明

0x01

解锁是必须遍历全图的,若只遍历当前屏幕的图元,会呈现这样的效果,屏幕外没有退出淡显:

0x02

e大告诉我这个神奇的地方,估计是触发了某些桌子内部机制,就好像WPF的数据绑定触发?
可以尝试注释掉这句再运行,会发现锁定褪色都不成功.acad08测试.
ltr.IsOff = ltr.IsOff;

相关说明

cad.net 图元动画效果+图元刷新

(完)

posted @ 2022-03-11 20:21  惊惊  阅读(677)  评论(0编辑  收藏  举报