图层操作QAP:

Q
通过代码修改图层状态(比如开关图层)后,绘图区不能实时更新图层状态,需要鼠标进入绘图区激活屏幕才会刷新,执行 Application.UpdateScreen() 方法也没用。
A
修改图层状态并提交事务后,先执行 TransactionManager.QueueForGraphicsFlush() ,再执行 UpdateScreen() 即可
P
注意,如果是调整了图层的冻结状态,需要执行 Editor.Regen() 来重生成才能够正常显示。图元数量大的话,重生成会很慢,导致界面卡顿,谨慎使用。

Q
可以通过代码很简单的设置当前图层,但系统当前图层改变事件就不那么容易捕捉,LayerTable 中也没有相关事件,最后在外网找到一个方法。
A
监视系统变量 CLAYER ,可通过订阅 Application.SystemVariableChanged 事件实现。

Q
图层冻结和删除的限制
A
当前图层不可冻结,可使用 Database.Clayer 或者 Application.GetSystemVariable(“CLAYER”) 获取当前图层来做比较,判断是否可冻结。
图层0、图层Defpoints、当前图层、有块参照的图层,有实体的图层均不能被删除,进行删除操作之前应注意


好吧,缝缝补补,也不知道今天具体完成了啥,图层管理器已经有个雏形了,各种事件响应、启动加载、界面联动、异常捕捉都基本搞定,右键菜单功能也有了思路,明天继续完善。。。


今天最大的收获应该是一个博客:Drive AutoCAD with Code ,博主是土木工程师出生,起码有个十几二十年的 AutoCAD 开发经验,附个ta的自我介绍:


After graduating from university, I worked as civil engineer for more than 10 years. It was AutoCAD use that led me to the path of computer programming. Although I now do more generic business software development, such as enterprise system, timesheet, billing, web services…, AutoCAD related programming is always interesting me and I still get AutoCAD programming tasks assigned to me from time to time. So, AutoCAD goes, I go.

博客满满都是干货,虽然全英文,而且浏览要翻墙,但完全值得啊,附一篇十年前的博文:


Tuesday, September 28, 2010
Pluggable PaletteSet

In ObjectARX .NET API, AutoCAD.Windows.PaletteSet class makes creating dockable floating winidow in AutoCAD a pretty easy thing to do. Many AutoCAD programmers use PaletteSet as a UI container to host a series of Palettes (Windows Form User Controls, usually).

Prior to AutoCAD 2009, PaletteSet is sealed class, e.g. it cannot be inherited as a base class to derive your own custom PaletteSet. Since AutoCAD 2009, PaletteSet class is not sealed any more. This opens a possiblity for our AutoCAD programmer to create a custom, generic PaletteSet UI container once, and develop pluggable palette based on business need and plug into the PaletteSet when needed (without any code change to the PaletteSet).

In this article, I’ll show how to use interface to define a pluggable PaletteSet. Interface is commonly used to define a set operations/properties for different classes to implement. It is one of the OO programming basic concept and used in .NET programming very often. However, there are many AutoCAD programmers who may not be a professional software developers and may too focused on AutoCAD API itself and did not explore some “advanced” programming technique enough, such as using “Interface” to simplify development tasks.

For this article, I demonstrate how to use Interface to create a pluggable PaletteSet. In Visual Stadio 2008, I started a class library project called MyPaletteSet, which includes 3 code files.

First code file is a interface that defines Palette that will be hosted in the pluggable PaletteSet: IThePalette. Later, when creating a Win Form UserControl as Palette, the UserControl will implement the interface. This, no matter how do you design your UserControls and how different they would be, to the hosting PaletteSet, they all are IThePalette. That is, the hosting PaletteSet does not have knowledge of each individual UserControl it hosts, as long as the UserControl is an IThePalette.

Here is the code:

    namespace MyPaletteSet{public interface IThePalette{ThePaletteSet PaletteSet { set; get; }string PaletteName { get; }void Close();void ClosePaletteSet();}}

Second code file is the custom PaletteSet, derived from Autodesk.AutoCAD.Windows.PaletteSet. As aforementioned, it is only possible when you use AutoCAD 2009 or later.

Here is the code:

    using System;using System.Drawing;using System.Collections.Generic;using Autodesk.AutoCAD.Windows;using Autodesk.AutoCAD.ApplicationServices;namespace MyPaletteSet{public class ThePaletteSet : PaletteSet{private static Guid _guid =new Guid("B9169E25-3EC1-442F-B518-46B2DA174A2F");private DocumentCollection _dwgManager = null;private List<IThePalette> _paltettes = new List<IThePalette>();public event DocumentCollectionEventHandler DwgBecameCurrent;public ThePaletteSet(): base("ThePaletteSet",null, _guid){this.Style = PaletteSetStyles.ShowAutoHideButton |PaletteSetStyles.ShowCloseButton |PaletteSetStyles.Snappable;this.Opacity = 100;this.Dock = DockSides.None;this.DockEnabled = DockSides.None;this.Size = new Size(500, 400);this.MinimumSize = new Size(250, 200);_dwgManager = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;//Handle DocumentCollection events to bubble up the event for IThePalette_dwgManager.DocumentBecameCurrent +=new DocumentCollectionEventHandler(_dwgManager_DocumentBecameCurrent);}private void _dwgManager_DocumentBecameCurrent(object sender, DocumentCollectionEventArgs e){if (DwgBecameCurrent != null){DwgBecameCurrent(this, e);}}public void AddPalette(IThePalette palette){bool exists = false;foreach (IThePalette plt in _paltettes){if (plt.PaletteName.ToUpper() == palette.PaletteName.ToUpper()){exists = true;break;}}if (!exists){System.Windows.Forms.Control ctl =palette as System.Windows.Forms.Control;//Add to palettesetthis.Add(palette.PaletteName, ctl);_paltettes.Add(palette);palette.PaletteSet = this;}}public void RemovePalette(string paletteName){if (_paltettes.Count == 0) return;for (int i = 0; i < _paltettes.Count; i++){if (_paltettes[i].PaletteName.ToUpper() == paletteName.ToUpper()){System.Windows.Forms.Control ctl =_paltettes[i] as System.Windows.Forms.Control;this.Remove(i);_paltettes.RemoveAt(i);ctl.Dispose();if (_paltettes.Count == 0) this.Visible = false;return;}}}public void ActivatePalette(string paletteName){if (_paltettes.Count == 0) return;for (int i = 0; i < _paltettes.Count; i++){if (_paltettes[i].PaletteName.ToUpper() == paletteName.ToUpper()){this.Activate(i);return;}}}}}

Pay attention to this line of code:

public event DocumentCollectionEventHandler DwgBecameCurrent;

and this line of code:

_dwgManager.DocumentBecameCurrent += new …

Some of your Palettes may be designed to handle drawing based data. Since PaletteSet is a floating/modeless window, when current drawing changed in AutoCAD, the data shown in certain palette should be refreshed because of current drawing change (like AutoCAD’s “Properties” window). Therefore, the this type of palette must be able to handle various events originally raised by DocumentCollection. So, here I simply handle the DocumentCollection events in the custom PaletteSet and bubble the events up. It is up to the individual Palette to subscribe the events when necessary. To simplfy the example, I only handle and raise the DocumentBecameCurrent event. In real production code, we could bubble up all the DocumentCollection events. The third code file is contains a static help method to create an instance of the custom PaletteSet. Here is the code:

    using Autodesk.AutoCAD.Runtime;[assembly: ExtensionApplication(typeof(MyPaletteSet.ThePaletteSetInitializer))]namespace MyPaletteSet{public class ThePaletteSetInitializer : IExtensionApplication{private static ThePaletteSet _paletteSet = null;public void Initialize(){//If necessary, add some code}public void Terminate(){if (_paletteSet != null) _paletteSet.Dispose();}public static ThePaletteSet CreateThePaltetteSet(IThePalette palette){if (_paletteSet == null){_paletteSet = new ThePaletteSet();}//Add palette to the PaletteSet_paletteSet.AddPalette(palette);return _paletteSet;}public static ThePaletteSet CreateThePaltetteSet(){if (_paletteSet == null){_paletteSet = new ThePaletteSet();}return _paletteSet;}}}

That’s it. Now we have a generic, pluggable PaletteSet. Build the project. From now on, when you want to build a suite of your own tools that have UI to be hosted in a PaletteSet, you can focus to the development of the Palette (Win Form UserControl) and never need to update the PaletteSet host and redeploy it. Let’s see a couple of sample palettes. Sample 1: FirstPalette. Start a new class library command. It can be in the same solution as the “MyPaletteSet”. But to better understand the “pluggable” nature, it is recommended to do this project in different solution. This will show that you can really focus on developing your Palette without having to update the PaletteSet at all. Once the project created, set reference to the DLL generated in “MyPaletteSet” project (MyPaletteSet.dll). Add a Win Form UserControl, called FirstPalette. It looks like:

Here is the code of the UserControl:

    using System;using System.Windows.Forms;using Autodesk.AutoCAD.ApplicationServices;using MyPaletteSet;namespace FirstPaletteTool{public partial class FirstPalette : UserControl, IThePalette{private ThePaletteSet _parent = null;public FirstPalette(){InitializeComponent();Document dwg = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;if (dwg != null) txtFileName.Text = dwg.Name;}#region IThePalette Memberspublic string PaletteName{get { return "First Palette"; }}public ThePaletteSet PaletteSet{get{return _parent;}set{_parent = value;_parent.DwgBecameCurrent +=new DocumentCollectionEventHandler(_parent_DwgBecameCurrent);}}void _parent_DwgBecameCurrent(object sender,DocumentCollectionEventArgs e){txtFileName.Text = e.Document.Name;}public void Close(){if (_parent != null){_parent.RemovePalette(this.PaletteName);}}public void ClosePaletteSet(){if (_parent != null) _parent.Visible = false;}#endregionprivate void button2_Click(object sender, EventArgs e){this.ClosePaletteSet();}private void button1_Click(object sender, EventArgs e){this.Close();}}}

Then add another class file into the project: FirstPaletteCommand. Here is the code:

    using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.Runtime;using MyPaletteSet;[assembly: CommandClass(typeof(FirstPaletteTool.FirstPaletteCommand))]namespace FirstPaletteTool{public class FirstPaletteCommand{private static ThePaletteSet _pltSet;[CommandMethod("StartFirst", CommandFlags.Session)]public static void RunThisMethod(){Document dwg = Application.DocumentManager.MdiActiveDocument;try{FirstPalette plt = new FirstPalette();_pltSet = MyPaletteSet.ThePaletteSetInitializer.CreateThePaltetteSet(plt);_pltSet.Visible = true;_pltSet.ActivatePalette(plt.PaletteName);}catch(System.Exception ex){dwg.Editor.WriteMessage("\nError: " + ex.Message);}}}}

Since I want this palette to show per-drawing based data, thus, I make this palette subscribe event “DwgBecameCurrent” raised by the hosting PaletteSet (MyPaletteSet). As you can see, no matter what UI components you place onto this palette (UserControl) and what code logic you will let this palette to execute, you can plug the palette into a common PaletteSet easily. New, let me create another palette: SecondPalette. Start a new class library project, called “SecondPaletteTool”, set reference to “MyPaletteSet.dll”. Add a Win Form UserControl, which looks like:

Its code is here:

    using System;using System.Windows.Forms;using MyPaletteSet;namespace SecondPaletteTool{public partial class SecondPalette : UserControl, IThePalette{private ThePaletteSet _parent = null;public SecondPalette(){InitializeComponent();}#region IThePalette Memberspublic ThePaletteSet PaletteSet{get{return _parent;}set{_parent = value;}}public string PaletteName{get { return "Second Palette"; }}public void Close(){if (_parent != null){_parent.RemovePalette(this.PaletteName);}}public void ClosePaletteSet(){if (_parent != null) _parent.Visible = false;}#endregionprivate void button1_Click(object sender, EventArgs e){this.Close();}private void button2_Click(object sender, EventArgs e){this.ClosePaletteSet();}}}

Notice that this palette does not subscribe event raised by hosting PaletteSet. Add a class into the project: SecondPaletteCommand:

    using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.Runtime;using MyPaletteSet;[assembly: CommandClass(typeof(SecondPaletteTool.SecondPaletteCommand))]namespace SecondPaletteTool{public class SecondPaletteCommand{private static ThePaletteSet _pltSet;[CommandMethod("StartSecond", CommandFlags.Session)]public static void RunThisMethod(){Document dwg = Application.DocumentManager.MdiActiveDocument;try{SecondPalette plt = new SecondPalette();_pltSet = MyPaletteSet.ThePaletteSetInitializer.CreateThePaltetteSet(plt);_pltSet.Visible = true;_pltSet.ActivatePalette(plt.PaletteName);}catch (System.Exception ex){dwg.Editor.WriteMessage("\nError: " + ex.Message);}}}}

As you can see, no matter how different the second palette from the first one, it can be plugged into MyPaletteSet in the same way, because, to MyPaletteSet, these 2 palettes are the same type: IMyPalette.

Now, start AutoCAD and “NETLOAD” the 2 palette projects (e.g. load FirstPaletteTool.dll and SecondPaletteTool.dll separately, as if the 2 DLLs are deployed and loaded separately). Enter command “StartFirst” and/or “StartSecond”. You can see the corresponding palette will be shown in a common PaletteSet. If you open more than one drawings in AutoCAD and switch the active drawing, you can see the file name shown on the “First Palette” changes accordingly, because this palette handles DwgBecameCurrent event raised by the hosting PaletteSet.

From now on, whenever I want to develop a new AutoCAD tool that would have a modeless window as UI, I can go ahead to develop the UI as Win Form UserControl. Once it is done, I can simply plug it into the common hosting PaletteSet. Since the newly developed palette is in its own project, it can be deployed independently to all existing palettes, yet they are hosted in the same PaletteSet.

In the FirstPalette, I have to add “using Autodesk.AutoCAD.ApplicationServices;” because the palette has to comsume DocumentCollectionEventArgs in the DwgBecameCurrent event handler. In real development code, it is best practice to not let the UserControl to be tied to AutoCAD’s dll. In this case, it is better to define my own custom EvenArgs and my own custom EventHandler in the MyPaletteSet project and use them to bubble up the various DocumentCollection events.


以上就是全文,亲测可用,Good Night

AutoCAD.NET开发:PaletteSet相关推荐

  1. 《AutoCAD .NET开发指南2012版》翻译整理已完成,欢迎大家下载!

    <AutoCAD .NET开发指南2012版>根据AutoDesk公司网站上的AutoCAD .NET Developer's Guide2012版翻译整理. 原始文档网址为 http:/ ...

  2. AutoCAD.Net开发问题之:层表事件的响应(续)

    之前在 AutoCAD.Net开发问题之:层表事件的响应 中,没找到直接响应层表的事件,就用了 Dababase 的 Object 相关事件来替代.在测试过程中发现监听图层变化的目的倒是达到了,但会严 ...

  3. AutoCAD .Net开发指南第4部分关于标注和公差的内容翻译完了!

    AutoCAD .Net开发指南第4部分关于标注和公差的内容翻译完了! 已经制作成pdf文件,有章节标签,欢迎大家下载指正. 下载地址: http://download.csdn.net/detail ...

  4. AutoCAD .NET开发(使用 ActiveX® 自动操作及支持 COM 的语言c#)

    我是文明,以下即代表我的个人认同看法,有不同看法的可以留言哈,谢谢你的阅读,文章有错字或代码错误请指正,谢谢你哦.  AutoCAD .NET开发 近期,项目需求需要进行CAD二次开发,以下为需求: ...

  5. 激动人心的AutoCAD .net开发技术

    自从了解了vsto和sc(SmartClient)技术后,对以前Win32的二次开发技术,再也没有一点兴趣.对Office VBA,  AutoCAD lisp, VBA,  PowerBuilder ...

  6. autocad .net开发指南_就业指南||职路明灯(二十)

    " 让我们走进新一期的就业指南, 寻找适合你的工作吧! 01 宝略科技(浙江)有限公司 招聘职位:GIS开发工程师 工资待遇:6-8千/月 学历要求:本科 招聘人数:3人 岗位职责: 1.负 ...

  7. AutoCAD .NET开发1:环境搭建

    AutoCAD,CAD(Computer Aided Design)计算机辅助设计,是计算机技术的一个重要的应用领域.AutoCAD是美国Autodesk公司开发的交互式绘图软件.其具有强大的功能,其 ...

  8. AutoCAD ObjectARX开发版本对照表

    免费AUTOCAD二次开发课程请关注 yunyou.ke.qq.com ObjectARX开发版本对照表 序号 CAD版本 版本号 二进制兼容 .net框架 ObjectARX开发环境 VC版本号 M ...

  9. 1、AutoCAD ObjectARX开发版本对照表

    ObjectARX开发版本对照表 序号 CAD版本 版本号 二进制兼容 .net框架 ObjectARX开发环境 VC版本号 MAC OS平台 WINDOWS平台 VC版本 _MSC_VER 1 R1 ...

  10. AutoCAD .NET开发大师Kean有价值的博客 2006年8月 .NET内容整理

    一 Calling AutoCAD commands from .NET 使用.NET调用AutoCAD命令 In this earlier entry I showed some technique ...

最新文章

  1. Protobuf3语言指南
  2. 写入访问权限冲突_全面介绍 Linux 权限
  3. 纽曼皮尔逊准则Matlab实现,基于聂曼-皮尔逊准则的skip模式快速选择方法
  4. 一个电脑多个github、gitlab、oschina账户
  5. thinkphp+mysql+join+where_thinkphp5.0 多join时where无法between
  6. Java常用Linux命令集合
  7. 行程匹配的算法python_节约里程算法的python实现
  8. Python seaborn 条形图
  9. 【WSN定位】基于matlab灰狼算法优化无线传感器非测距定位【含Matlab源码 2008期】
  10. 解决CentOS安装VM Tools出现在客户机中装载CD驱动器启动终端,使用tar解压缩安装程序,然后执行vmware-insall.pl安装VMware Tools的问题。
  11. 六一快乐!管她几岁,快乐万岁!
  12. 推荐3个游戏小程序,让你整个暑假都充实!
  13. python自省与反射
  14. 一 简单句和并列句(2021-10-29)
  15. forward 与 redirect 的区别?有哪些方式实现
  16. Android:单元测试
  17. mysql如何重复数据合并_mysql合并相同字段,不同的拼接在起后
  18. python内置函数slice()
  19. 虚拟化基础-华为云计算虚拟化
  20. 孝经白话:天子章第二

热门文章

  1. 切比雪夫不等式例题讲解_数学广角:切比雪夫最佳逼近直线
  2. ubuntu22.04LTS 外接hdmi没有声音
  3. 桶装水同城预订下单送水小程序开发制作(水站桶装水配送系统)
  4. 评估分形指数和HURST指数预测金融时间序列的能力
  5. 爬虫 第二讲 urllib模块和requests模块
  6. 什么是平面设计,平面设计主要做什么?
  7. 读取Xilinx FPGA芯片的唯一ID号DNA
  8. 5.1.3 NoSQL数据库-Redis(键值key-value)-五大数据类型
  9. C语言零基础——简单门票费程序
  10. 市场营销商业指标统计分析