CAD二次开发 学习笔记(3)
CAD二次开发 学习笔记(3)
Excel数据存储测试
/// <summary> /// 从database读取直线的数据,并将数据保存到excel表 /// </summary> [CommandMethod("ToExcel")] public void ToExcel() { Database db = HostApplicationServices.WorkingDatabase; System.Data.DataTable table = new System.Data.DataTable(); table.TableName = "直线表"; table.Columns.Add("操作", typeof(string)); table.Columns.Add("起点坐标X",typeof(double )); table.Columns.Add("起点坐标Y", typeof(double)); table.Columns.Add("起点坐标Z", typeof(double)); table.Columns.Add("终点坐标X", typeof(double)); table.Columns.Add("终点坐标Y", typeof(double)); table.Columns.Add("终点坐标Z", typeof(double)); using (Transaction tr=db.TransactionManager.StartTransaction()) { BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; foreach (ObjectId objectId in btr) { Line line = tr.GetObject(objectId,OpenMode.ForRead) as Line; System.Data.DataRow row = table.NewRow(); if (line!=null) { row[0] = line.Handle.ToString(); row[1] = line.StartPoint.X; row[2] = line.StartPoint.Y; row[3] = line.StartPoint.Z; row[4] = line.EndPoint.X; row[5] = line.EndPoint.Y; row[6] = line.EndPoint.Z; } table.Rows.Add(row); } tr.Commit(); } SaveTo(table, @"C:\Users\Administrator\Desktop\LineData.xlsx"); } /// <summary> /// 将数据保存到excel表格 /// </summary> /// <param name="table"></param> /// <param name="fileName"></param> private void SaveTo(System.Data.DataTable table, string fileName) { int columnIndex = 1; int rowIndex = 1; Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application(); excelApp.DefaultFilePath = fileName; excelApp.DisplayAlerts = true; excelApp.SheetsInNewWorkbook = 1; Microsoft.Office.Interop.Excel.Workbook workbook = excelApp.Workbooks.Add(true); foreach (System.Data.DataColumn column in table.Columns) { excelApp.Cells[rowIndex, columnIndex] = column.ColumnName; columnIndex++; } for (int i = 0; i < table.Rows.Count; i++) { columnIndex = 1; rowIndex++; for (int j = 0; j < table.Columns.Count; j++) { excelApp.Cells[rowIndex, columnIndex] = table.Rows[i][j].ToString(); columnIndex++; } } workbook.SaveCopyAs(fileName); excelApp = null; workbook = null; }
运行结果
规则重定义OverRule
注意:该规则重定义不支持Jig绘制直线,只能静态生成,否则会导致CAD崩溃;
AddLine命令就是为了测试OverRule而专门添加的静态画直线方法;
//-------------规则重定义------------------- /// <summary> /// 开启规则重定义 /// </summary> [CommandMethod("StartOverRule")] public void StartOverRule() { LineToPipe lineToPipe = new LineToPipe(10); Overrule.AddOverrule(RXClass.GetClass(typeof(Line)), lineToPipe, false); Overrule.Overruling = true; } /// <summary> /// 结束规则重定义 /// </summary> [CommandMethod("EndOverRule")] public void EndOverRule() { Overrule.Overruling = false; } /// <summary> /// 添加一条直线:测试 /// </summary> [CommandMethod("AddLine")] public void AddLine() { Random r = new Random(); Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr =db.TransactionManager.StartTransaction()) { BlockTable bt = tr.GetObject(db.BlockTableId,OpenMode.ForRead) as BlockTable; BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace],OpenMode.ForWrite) as BlockTableRecord; Line line = new Line(new Point3d(r.Next(0,500), r.Next(0, 200),0), new Point3d(r.Next(0, 500), r.Next(0, 200), 0)); btr.AppendEntity(line); tr.AddNewlyCreatedDBObject(line ,true); tr.Commit(); } }
规则重定义的类
/// <summary> /// 规则重定义的类 /// </summary> public class LineToPipe : DrawableOverrule { private double r; public LineToPipe(double radius) { r = radius; } public override bool WorldDraw(Drawable drawable, WorldDraw wd) { if (drawable is Line) { Line line = drawable as Line; Circle circle = new Circle(line.StartPoint, line.EndPoint - line.StartPoint, r); ExtrudedSurface pipe = new ExtrudedSurface(); pipe.CreateExtrudedSurface(circle, line.EndPoint - line.StartPoint, new SweepOptions()); pipe.WorldDraw(wd); circle.Dispose(); pipe.Dispose(); } return true; } }
运行结果
CAD事件Event-EventHandler
//--------------------事件----------------------- /// <summary> /// 移除对象删除事件的处理函数/移除事件侦听者 /// </summary> [CommandMethod("RemoveErasedObjectEvent")] public void RemoveErasedObjectEvent() { Database db = HostApplicationServices.WorkingDatabase; db.ObjectErased -= new ObjectErasedEventHandler(ObjectErasedEventHandler); } /// <summary> /// 添加对象删除事件的处理函数/添加事件侦听者 /// </summary> [CommandMethod("AddErasedObjectEvent")] public void AddErasedObjectEvent() { Database db = HostApplicationServices.WorkingDatabase; //db.ObjectErased += ObjectErasedHandler;//方法一、委托添加方法 db.ObjectErased += new ObjectErasedEventHandler(ObjectErasedEventHandler);//方法二、委托添加委托 } /// <summary> /// 对象删除事件的处理函数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ObjectErasedEventHandler(object sender, ObjectErasedEventArgs e) { Application.ShowAlertDialog($"删除的对象Id为:{e.DBObject.ObjectId}"); }
运行结果
交互界面总结
添加右键菜单
/// <summary> /// 添加右键菜单 /// </summary> [CommandMethod("AddContextMenu")] public void AddContextMenu() { ContextMenuExtension contextMenu = new ContextMenuExtension(); contextMenu.Title = "我的右键菜单"; MenuItem item1 = new MenuItem("创建直线"); item1.Click += new EventHandler(item1_Click); MenuItem item2 = new MenuItem("创建圆"); item2.Click += new EventHandler(item2_Click); contextMenu.MenuItems.Add(item1); contextMenu.MenuItems.Add(item2); Application.AddDefaultContextMenuExtension(contextMenu); } private void item2_Click(object sender, EventArgs e) { Document doc = Application.DocumentManager.MdiActiveDocument; doc.SendStringToExecute("\nCircle",true,false,true); } private void item1_Click(object sender, EventArgs e) { Document doc = Application.DocumentManager.MdiActiveDocument; doc.SendStringToExecute("\nLine", true, false, true); }
运行结果
添加Ribbon菜单
/// <summary> /// 添加菜单命令 /// </summary> [CommandMethod("AddRibbon")] public void AddRibbon() { RibbonControl control = RibbonControl(); RibbonTab tab = RibbonTab("菜单标签1", "1"); RibbonTab tab2 = RibbonTab("菜单标签2", "2"); RibbonTab tab3 = RibbonTab("菜单标签3", "3"); RibbonPanel panel = RibbonPanel("菜单面板1"); RibbonPanel panel2 = RibbonPanel("菜单面板2"); RibbonPanel panel3 = RibbonPanel("菜单面板3"); RibbonPanel panel4 = RibbonPanel("菜单面板4"); RibbonButton button = RibbonButton("菜单按钮1", "菜单命令"); RibbonButton button2 = RibbonButton("菜单按钮2", "菜单命令"); RibbonButton button3 = RibbonButton("菜单按钮3", "菜单命令"); RibbonButton button4 = RibbonButton("菜单按钮4", "菜单命令"); panel.Source.Items.Add(button); panel.Source.Items.Add(button2); panel.Source.Items.Add(button3); panel.Source.Items.Add(button4); tab.Panels.Add(panel); tab.Panels.Add(panel2); tab.Panels.Add(panel3); tab.Panels.Add(panel4); control.Tabs.Add(tab); control.Tabs.Add(tab2); control.Tabs.Add(tab3); } /// <summary> /// 获得菜单控制 /// </summary> /// <returns></returns> public RibbonControl RibbonControl() { if (ComponentManager.Ribbon == null) { ComponentManager.ItemInitialized += new EventHandler<RibbonItemEventArgs>(ComponentManager_ItemInitialized); } return ComponentManager.Ribbon; } /// <summary> /// 用于激活菜单 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ComponentManager_ItemInitialized(object sender, RibbonItemEventArgs e) { if (ComponentManager.Ribbon != null) { ComponentManager.ItemInitialized -= new EventHandler<RibbonItemEventArgs>(ComponentManager_ItemInitialized); } } /// <summary> /// 创建菜单标签 /// </summary> /// <param name="name">标签名称</param> /// <param name="id">标签Id</param> /// <returns></returns> public RibbonTab RibbonTab(string name, string id) { RibbonTab tab = new RibbonTab() { Title = "Title:"+name, Id = id, IsActive = true, }; return tab; } /// <summary> /// 创建菜单面板 /// </summary> /// <param name="title">面板名称</param> /// <returns></returns> public RibbonPanel RibbonPanel(string title) { RibbonPanelSource source = new RibbonPanelSource(); source.Title = title; RibbonPanel panel = new RibbonPanel(); panel.Source = source; return panel; } /// <summary> /// 创建按钮 /// </summary> /// <param name="buttonName"></param> /// <param name="commandName"></param> /// <returns></returns> public RibbonButton RibbonButton(string buttonName, string commandName) { RibbonButton button = new RibbonButton() { Text = "Text:" + buttonName, CommandParameter = commandName, ShowText = true, CommandHandler = new AdCommandHandler(), }; return button; }
运行结果
添加自定义窗口面板
/// <summary> /// 自定义面板Palette /// </summary> [CommandMethod("AddPalette")] public void AddPalette() { CustomController controller = new CustomController(); PaletteSet ps = new PaletteSet("我的自定义面板") { Visible = true, Style = PaletteSetStyles.ShowAutoHideButton, Dock = DockSides.None, MinimumSize = new Size(200, 100), Size = new Size(400,200), }; ps.Add("自定义控件",controller); ps.Visible = true; }
运行结果
菜单层级结构
基础知识:
嵌入 AutoCAD 的窗体有两种:
ModalDialog(模态对话框), Application.ShowModalDialog(form);
ModelessDialog(非模态对话框) , Application.ShowModelessDialog(form);
一、模态对话框
ModalDialog(模态对话框)为不可切换焦点的对话框, 模态窗体显示的时候程序的焦点始终保持在模态窗体上;
如果需要切换到 AutoCAD 环境进行交互的时候需要EditorUserInteraction 类来切换焦点到 AutoCAD 的命令行;
如果将焦点从CAD切换回窗口,首先需要结束EditorUserInteraction ,然后再用Focus()方法将焦点重新回到窗体;
二、非模态对话框
ModelessDialog(非模态对话框)为活动焦点的对话框,程序焦点可以自由的从 AutoCAD 界面到窗体之间切换,主要用于
用户与 AutoCAD 环境的即时交互操作。
using (EditorUserInteraction edUsrInt = ed.StartUserInteraction(this))
{
//交互过程
edUsrInt.End(); //交互结束.
this.Focus();
}
交互测试-通过窗口选择点
/// <summary> /// 通过交互窗口选择点 /// </summary> [CommandMethod("SelectPointDialog")] public void SelectPointDialog() { using (SelectPointForm form=new SelectPointForm()) { //像CAD提示窗口一样,不在任务栏显示 form.ShowInTaskbar = false; //将form窗口作为模态窗口进行显示 Application.ShowModalDialog(form); //将textBox1的文本信息,显示到Editor窗口 Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(form.textBox1.Text); } }
/// <summary> /// 将焦点切换至CAD,以便选择点 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; using (EditorUserInteraction interaction = ed.StartUserInteraction(this)) { Point3d point = GetPoint3D("\n选择点"); textBox1.Text = $"选择点的坐标 X:{point.X},Y:{point.Y},Z:{point.Z}"; interaction.End(); this.Focus(); } } /// <summary> /// 提示用户拾取一个点 /// </summary> /// <param name="promptMessage"></param> /// <returns></returns> public Point3d GetPoint3D(string promptMessage) { Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor; PromptPointResult result = ed.GetPoint(promptMessage); if (result.Status == PromptStatus.OK) { return result.Value; } else { return new Point3d(); } } /// <summary> /// 确认按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.OK; this.Close(); } /// <summary> /// 取消按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.Cancel; this.Close(); } }
运行结果
打印输出相关类的关系图
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!