CAD二次开发 学习笔记(3)
CAD二次开发 学习笔记(3)
Excel数据存储测试
///
/// 从database读取直线的数据,并将数据保存到excel表
///
[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");
}
///
/// 将数据保存到excel表格
///
///
///
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而专门添加的静态画直线方法;
//-------------规则重定义-------------------
///
/// 开启规则重定义
///
[CommandMethod("StartOverRule")]
public void StartOverRule()
{
LineToPipe lineToPipe = new LineToPipe(10);
Overrule.AddOverrule(RXClass.GetClass(typeof(Line)), lineToPipe, false);
Overrule.Overruling = true;
}
///
/// 结束规则重定义
///
[CommandMethod("EndOverRule")]
public void EndOverRule()
{
Overrule.Overruling = false;
}
///
/// 添加一条直线:测试
///
[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();
}
}
规则重定义的类
///
/// 规则重定义的类
///
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
//--------------------事件-----------------------
///
/// 移除对象删除事件的处理函数/移除事件侦听者
///
[CommandMethod("RemoveErasedObjectEvent")]
public void RemoveErasedObjectEvent()
{
Database db = HostApplicationServices.WorkingDatabase;
db.ObjectErased -= new ObjectErasedEventHandler(ObjectErasedEventHandler);
}
///
/// 添加对象删除事件的处理函数/添加事件侦听者
///
[CommandMethod("AddErasedObjectEvent")]
public void AddErasedObjectEvent()
{
Database db = HostApplicationServices.WorkingDatabase;
//db.ObjectErased += ObjectErasedHandler;//方法一、委托添加方法
db.ObjectErased += new ObjectErasedEventHandler(ObjectErasedEventHandler);//方法二、委托添加委托
}
///
/// 对象删除事件的处理函数
///
///
///
private void ObjectErasedEventHandler(object sender, ObjectErasedEventArgs e)
{
Application.ShowAlertDialog($"删除的对象Id为:{e.DBObject.ObjectId}");
}
运行结果
交互界面总结
添加右键菜单
///
/// 添加右键菜单
///
[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菜单
///
/// 添加菜单命令
///
[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);
}
///
/// 获得菜单控制
///
///
public RibbonControl RibbonControl()
{
if (ComponentManager.Ribbon == null)
{
ComponentManager.ItemInitialized +=
new EventHandler(ComponentManager_ItemInitialized);
}
return ComponentManager.Ribbon;
}
///
/// 用于激活菜单
///
///
///
private void ComponentManager_ItemInitialized(object sender, RibbonItemEventArgs e)
{
if (ComponentManager.Ribbon != null)
{
ComponentManager.ItemInitialized -= new EventHandler(ComponentManager_ItemInitialized);
}
}
///
/// 创建菜单标签
///
/// 标签名称
/// 标签Id
///
public RibbonTab RibbonTab(string name, string id)
{
RibbonTab tab = new RibbonTab()
{
Title = "Title:"+name,
Id = id,
IsActive = true,
};
return tab;
}
///
/// 创建菜单面板
///
/// 面板名称
///
public RibbonPanel RibbonPanel(string title)
{
RibbonPanelSource source = new RibbonPanelSource();
source.Title = title;
RibbonPanel panel = new RibbonPanel();
panel.Source = source;
return panel;
}
///
/// 创建按钮
///
///
///
///
public RibbonButton RibbonButton(string buttonName, string commandName)
{
RibbonButton button = new RibbonButton()
{
Text = "Text:" + buttonName,
CommandParameter = commandName,
ShowText = true,
CommandHandler = new AdCommandHandler(),
};
return button;
}
运行结果
添加自定义窗口面板
///
/// 自定义面板Palette
///
[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();
}
交互测试-通过窗口选择点
///
/// 通过交互窗口选择点
///
[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);
}
}
///
/// 将焦点切换至CAD,以便选择点
///
///
///
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();
}
}
///
/// 提示用户拾取一个点
///
///
///
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();
}
}
///
/// 确认按钮
///
///
///
private void button2_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
///
/// 取消按钮
///
///
///
private void button3_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
运行结果
打印输出相关类的关系图