using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
// 使用别名解决命名冲突
using AcApp = Autodesk.AutoCAD.ApplicationServices.Application;
using WinApp = System.Windows.Forms.Application;
// 程序集特性必须放在命名空间之前
[assembly: CommandClass(typeof(InsertFramePlugin.InsertFrameCommands))]
namespace InsertFramePlugin
{
public class InsertFrameCommands
{
[CommandMethod("IFR", CommandFlags.Modal)]
public void InsertFrame()
{
Document doc = AcApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
try
{
var form = new InsertFrameForm();
DialogResult result = AcApp.ShowModalDialog(form);
if (result == DialogResult.OK)
{
ed.WriteMessage("\n图框插入操作完成。");
}
}
catch (System.Exception ex)
{
ed.WriteMessage($"\n错误: {ex.Message}");
}
}
}
// 标题栏属性编辑窗体
public class TitleBlockEditForm : Form
{
private TextBox tbUnitName, tbProjectManager, tbSpecialtyManager, tbTechManager,
tbProjectName, tbDrawingName, tbSubPart, tbDrawingNo, tbScale, tbDate;
private TextBox tbDrawer, tbChecker, tbApprover;
private Button btnOK, btnCancel;
public Dictionary<string, string> AttributeValues { get; private set; }
public TitleBlockEditForm(Dictionary<string, string> currentValues)
{
AttributeValues = new Dictionary<string, string>();
InitializeComponents(currentValues);
}
private void InitializeComponents(Dictionary<string, string> currentValues)
{
this.Text = "标题栏属性编辑";
this.Size = new System.Drawing.Size(500, 450);
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
int yPos = 10;
int labelWidth = 80;
int textBoxWidth = 200;
// 第一行
var lblUnitName = new Label { Text = "单位名称:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbUnitName = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("单位名称") ? currentValues["单位名称"] : "" };
this.Controls.Add(lblUnitName);
this.Controls.Add(tbUnitName);
yPos += 30;
var lblProjectName = new Label { Text = "工程名称:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbProjectName = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("工程名称") ? currentValues["工程名称"] : "" };
this.Controls.Add(lblProjectName);
this.Controls.Add(tbProjectName);
yPos += 30;
var lblSubPart = new Label { Text = "分部分项:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbSubPart = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("分部分项") ? currentValues["分部分项"] : "" };
this.Controls.Add(lblSubPart);
this.Controls.Add(tbSubPart);
// 第二行
yPos += 30;
var lblDrawer = new Label { Text = "制图人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbDrawer = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("制图人") ? currentValues["制图人"] : "" };
this.Controls.Add(lblDrawer);
this.Controls.Add(tbDrawer);
yPos += 30;
var lblProjectManager = new Label { Text = "工程负责人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbProjectManager = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("工程负责人") ? currentValues["工程负责人"] : "" };
this.Controls.Add(lblProjectManager);
this.Controls.Add(tbProjectManager);
yPos += 30;
var lblDrawingNo = new Label { Text = "图号:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbDrawingNo = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("图号") ? currentValues["图号"] : "" };
this.Controls.Add(lblDrawingNo);
this.Controls.Add(tbDrawingNo);
// 第三行
yPos += 30;
var lblChecker = new Label { Text = "审核人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbChecker = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("审核人") ? currentValues["审核人"] : "" };
this.Controls.Add(lblChecker);
this.Controls.Add(tbChecker);
yPos += 30;
var lblSpecialtyManager = new Label { Text = "专业负责人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbSpecialtyManager = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("专业负责人") ? currentValues["专业负责人"] : "" };
this.Controls.Add(lblSpecialtyManager);
this.Controls.Add(tbSpecialtyManager);
yPos += 30;
var lblDrawingName = new Label { Text = "图纸名称:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbDrawingName = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("图纸名称") ? currentValues["图纸名称"] : "" };
this.Controls.Add(lblDrawingName);
this.Controls.Add(tbDrawingName);
yPos += 30;
var lblScale = new Label { Text = "比例:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbScale = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("比例") ? currentValues["比例"] : "" };
this.Controls.Add(lblScale);
this.Controls.Add(tbScale);
// 第四行
yPos += 30;
var lblApprover = new Label { Text = "审定人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbApprover = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("审定人") ? currentValues["审定人"] : "" };
this.Controls.Add(lblApprover);
this.Controls.Add(tbApprover);
yPos += 30;
var lblTechManager = new Label { Text = "技术负责人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbTechManager = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("技术负责人") ? currentValues["技术负责人"] : "" };
this.Controls.Add(lblTechManager);
this.Controls.Add(tbTechManager);
yPos += 30;
var lblDate = new Label { Text = "日期:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth };
tbDate = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("日期") ? currentValues["日期"] : DateTime.Now.ToString("yyyy-MM-dd") };
this.Controls.Add(lblDate);
this.Controls.Add(tbDate);
// 按钮
yPos += 40;
btnOK = new Button { Text = "确定", Location = new System.Drawing.Point(150, yPos), Width = 80 };
btnCancel = new Button { Text = "取消", Location = new System.Drawing.Point(250, yPos), Width = 80 };
btnOK.Click += (s, e) =>
{
// 保存所有值
AttributeValues["单位名称"] = tbUnitName.Text;
AttributeValues["工程名称"] = tbProjectName.Text;
AttributeValues["分部分项"] = tbSubPart.Text;
AttributeValues["制图人"] = tbDrawer.Text;
AttributeValues["工程负责人"] = tbProjectManager.Text;
AttributeValues["图号"] = tbDrawingNo.Text;
AttributeValues["审核人"] = tbChecker.Text;
AttributeValues["专业负责人"] = tbSpecialtyManager.Text;
AttributeValues["图纸名称"] = tbDrawingName.Text;
AttributeValues["比例"] = tbScale.Text;
AttributeValues["审定人"] = tbApprover.Text;
AttributeValues["技术负责人"] = tbTechManager.Text;
AttributeValues["日期"] = tbDate.Text;
this.DialogResult = DialogResult.OK;
this.Close();
};
btnCancel.Click += (s, e) =>
{
this.DialogResult = DialogResult.Cancel;
this.Close();
};
this.Controls.Add(btnOK);
this.Controls.Add(btnCancel);
}
}
public partial class InsertFrameForm : Form
{
// 窗体控件
private RadioButton rbA0, rbA1, rbA2, rbA3, rbA4;
private ComboBox cbExtension;
private RadioButton rbHorizontal, rbVertical;
private TextBox tbLength, tbWidth;
private CheckBox cbTitleBlock;
private TextBox tbScale;
private Button btnAuto, btnManual, btnCancel;
// 图幅尺寸定义 (mm)
private readonly Dictionary<string, PaperSize> paperSizes = new Dictionary<string, PaperSize>
{
{"A0", new PaperSize(841, 1189)},
{"A1", new PaperSize(594, 841)},
{"A2", new PaperSize(420, 594)},
{"A3", new PaperSize(297, 420)},
{"A4", new PaperSize(210, 297)}
};
// 加长系数
private readonly Dictionary<string, double> extensions = new Dictionary<string, double>
{
{"A0+1/8", 1.125},
{"A0+1/4", 1.25},
{"A0+3/8", 1.375},
{"A0+1/2", 1.5},
{"A0+5/8", 1.625},
{"A0+3/4", 1.75},
{"A0+7/8", 1.875},
{"A0+1", 2.0}
};
public InsertFrameForm()
{
InitializeComponents();
}
private void InitializeComponents()
{
// 窗体设置
this.Text = "插入图框 v1.0";
this.Size = new System.Drawing.Size(450, 300);
this.StartPosition = FormStartPosition.CenterScreen;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
// 第一行:图幅选择
var groupPaperSize = new GroupBox
{
Text = "图幅",
Location = new System.Drawing.Point(10, 10),
Size = new System.Drawing.Size(420, 50)
};
rbA0 = new RadioButton { Text = "A0", Location = new System.Drawing.Point(10, 20), AutoSize = true };
rbA1 = new RadioButton { Text = "A1", Location = new System.Drawing.Point(60, 20), AutoSize = true };
rbA2 = new RadioButton { Text = "A2", Location = new System.Drawing.Point(110, 20), AutoSize = true, Checked = true };
rbA3 = new RadioButton { Text = "A3", Location = new System.Drawing.Point(160, 20), AutoSize = true };
rbA4 = new RadioButton { Text = "A4", Location = new System.Drawing.Point(210, 20), AutoSize = true };
cbExtension = new ComboBox
{
Location = new System.Drawing.Point(260, 18),
Width = 150,
DropDownStyle = ComboBoxStyle.DropDownList
};
cbExtension.Items.AddRange(new object[] {
"无加长",
"A0+1/8", "A0+1/4", "A0+3/8", "A0+1/2",
"A0+5/8", "A0+3/4", "A0+7/8", "A0+1"
});
cbExtension.SelectedIndex = 0;
groupPaperSize.Controls.AddRange(new Control[] { rbA0, rbA1, rbA2, rbA3, rbA4, cbExtension });
// 第二行:方向与尺寸
var groupOrientation = new GroupBox
{
Text = "方向",
Location = new System.Drawing.Point(10, 70),
Size = new System.Drawing.Size(120, 50)
};
rbHorizontal = new RadioButton { Text = "横式", Location = new System.Drawing.Point(10, 20), AutoSize = true, Checked = true };
rbVertical = new RadioButton { Text = "立式", Location = new System.Drawing.Point(65, 20), AutoSize = true };
groupOrientation.Controls.AddRange(new Control[] { rbHorizontal, rbVertical });
var groupDimensions = new GroupBox
{
Text = "自定义尺寸 (mm)",
Location = new System.Drawing.Point(140, 70),
Size = new System.Drawing.Size(290, 50)
};
tbLength = new TextBox { Location = new System.Drawing.Point(50, 20), Width = 80, Text = "594" };
tbWidth = new TextBox { Location = new System.Drawing.Point(180, 20), Width = 80, Text = "420" };
groupDimensions.Controls.AddRange(new Control[] {
new Label { Text = "长:", Location = new System.Drawing.Point(10, 23), AutoSize = true },
tbLength,
new Label { Text = "宽:", Location = new System.Drawing.Point(140, 23), AutoSize = true },
tbWidth
});
// 第三行:标题栏和比例
var groupSettings = new GroupBox
{
Text = "设置",
Location = new System.Drawing.Point(10, 130),
Size = new System.Drawing.Size(420, 50)
};
cbTitleBlock = new CheckBox
{
Text = "标准标题栏",
Location = new System.Drawing.Point(10, 20),
AutoSize = true,
Checked = true
};
tbScale = new TextBox
{
Text = "100",
Location = new System.Drawing.Point(350, 20),
Width = 50
};
groupSettings.Controls.AddRange(new Control[] {
cbTitleBlock,
new Label { Text = "比例 1:", Location = new System.Drawing.Point(300, 23), AutoSize = true },
tbScale
});
// 第四行:操作按钮
btnAuto = new Button
{
Text = "框选图自动布置图框",
Location = new System.Drawing.Point(10, 190),
Width = 140,
BackColor = System.Drawing.Color.LightBlue
};
btnManual = new Button
{
Text = "手动插入",
Location = new System.Drawing.Point(160, 190),
Width = 100,
BackColor = System.Drawing.Color.LightGreen
};
btnCancel = new Button
{
Text = "取消",
Location = new System.Drawing.Point(270, 190),
Width = 100,
BackColor = System.Drawing.Color.LightSalmon
};
// 事件处理
btnAuto.Click += BtnAuto_Click;
btnManual.Click += BtnManual_Click;
btnCancel.Click += (s, e) => { this.DialogResult = DialogResult.Cancel; this.Close(); };
// 单选按钮事件处理
rbA0.CheckedChanged += PaperSizeChanged;
rbA1.CheckedChanged += PaperSizeChanged;
rbA2.CheckedChanged += PaperSizeChanged;
rbA3.CheckedChanged += PaperSizeChanged;
rbA4.CheckedChanged += PaperSizeChanged;
rbHorizontal.CheckedChanged += (s, e) => UpdateDimensionsFromSelection();
rbVertical.CheckedChanged += (s, e) => UpdateDimensionsFromSelection();
// 加长系数选择事件
cbExtension.SelectedIndexChanged += (s, e) => UpdateDimensionsFromSelection();
// 初始化尺寸显示
UpdateDimensionsFromSelection();
// 添加所有控件
this.Controls.AddRange(new Control[] {
groupPaperSize,
groupOrientation,
groupDimensions,
groupSettings,
btnAuto,
btnManual,
btnCancel
});
}
private void PaperSizeChanged(object sender, EventArgs e)
{
if (rbA0.Checked) UpdateDimensions("A0");
else if (rbA1.Checked) UpdateDimensions("A1");
else if (rbA2.Checked) UpdateDimensions("A2");
else if (rbA3.Checked) UpdateDimensions("A3");
else if (rbA4.Checked) UpdateDimensions("A4");
}
private void UpdateDimensions(string sizeKey)
{
if (paperSizes.TryGetValue(sizeKey, out PaperSize size))
{
// 修复方向问题:现在横式就是宽度>高度,立式就是高度>宽度
if (rbHorizontal.Checked)
{
// 横式:宽度 > 高度
tbLength.Text = Math.Max(size.Width, size.Height).ToString();
tbWidth.Text = Math.Min(size.Width, size.Height).ToString();
}
else
{
// 立式:高度 > 宽度
tbLength.Text = Math.Min(size.Width, size.Height).ToString();
tbWidth.Text = Math.Max(size.Width, size.Height).ToString();
}
// 应用加长系数
if (cbExtension.SelectedItem != null &&
cbExtension.SelectedIndex > 0 &&
extensions.TryGetValue(cbExtension.SelectedItem.ToString(), out double extFactor))
{
if (rbHorizontal.Checked)
{
// 横式时加长长边(长度)
double newLength = double.Parse(tbLength.Text) * extFactor;
tbLength.Text = Math.Round(newLength).ToString();
}
else
{
// 立式时加长长边(宽度)
double newWidth = double.Parse(tbWidth.Text) * extFactor;
tbWidth.Text = Math.Round(newWidth).ToString();
}
}
}
}
private void UpdateDimensionsFromSelection()
{
if (rbA0.Checked) UpdateDimensions("A0");
else if (rbA1.Checked) UpdateDimensions("A1");
else if (rbA2.Checked) UpdateDimensions("A2");
else if (rbA3.Checked) UpdateDimensions("A3");
else if (rbA4.Checked) UpdateDimensions("A4");
}
private void BtnAuto_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
this.Close();
Document doc = AcApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
try
{
// 获取选择集
PromptSelectionOptions pso = new PromptSelectionOptions();
pso.MessageForAdding = "\n选择要包围的图形对象: ";
PromptSelectionResult selRes = ed.GetSelection(pso);
if (selRes.Status != PromptStatus.OK)
{
return;
}
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Extents3d overallExtent = new Extents3d();
bool first = true;
foreach (SelectedObject selObj in selRes.Value)
{
Entity ent = tr.GetObject(selObj.ObjectId, OpenMode.ForRead) as Entity;
if (ent != null)
{
Extents3d entExtents = ent.GeometricExtents;
if (first)
{
overallExtent = entExtents;
first = false;
}
else
{
overallExtent.AddExtents(entExtents);
}
}
}
if (first)
{
ed.WriteMessage("\n未选择到有效的图形对象。");
return;
}
// 计算图框尺寸
PaperSize frameSize = CalculateFrameSize();
double frameWidth = frameSize.Width;
double frameHeight = frameSize.Height;
// 计算内容尺寸
double contentWidth = overallExtent.MaxPoint.X - overallExtent.MinPoint.X;
double contentHeight = overallExtent.MaxPoint.Y - overallExtent.MinPoint.Y;
if (contentWidth <= 0 || contentHeight <= 0)
{
ed.WriteMessage("\n选择的图形没有有效的范围。");
return;
}
// 添加边距
double margin = Math.Min(contentWidth, contentHeight) * 0.1;
// 计算缩放比例以确保内容适合图框
double scaleX = (frameWidth - 2 * margin) / contentWidth;
double scaleY = (frameHeight - 2 * margin) / contentHeight;
double scale = Math.Min(scaleX, scaleY);
// 如果内容比图框小很多,使用1:1比例
if (scale > 1) scale = 1;
// 计算内容中心点
Point3d contentCenter = new Point3d(
(overallExtent.MinPoint.X + overallExtent.MaxPoint.X) / 2,
(overallExtent.MinPoint.Y + overallExtent.MaxPoint.Y) / 2,
0);
// 计算图框插入点(使内容居中于图框)
Point2d insertionPoint = new Point2d(
contentCenter.X - (frameWidth / 2 / scale),
contentCenter.Y - (frameHeight / 2 / scale));
// 插入图框
InsertFrameBlock(insertionPoint, frameWidth, frameHeight, tr, db);
tr.Commit();
ed.WriteMessage($"\n图框自动布置完成! 图框尺寸: {frameWidth:F0} x {frameHeight:F0}");
}
}
catch (System.Exception ex)
{
ed.WriteMessage($"\n自动布置错误: {ex.Message}");
}
}
private void BtnManual_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
this.Close();
Document doc = AcApp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
try
{
// 获取插入点
PromptPointOptions ppo = new PromptPointOptions("\n指定图框左下角点: ");
PromptPointResult ptRes = ed.GetPoint(ppo);
if (ptRes.Status != PromptStatus.OK)
{
return;
}
// 计算图框尺寸
PaperSize frameSize = CalculateFrameSize();
double frameWidth = frameSize.Width;
double frameHeight = frameSize.Height;
// 插入图框
using (Transaction tr = db.TransactionManager.StartTransaction())
{
InsertFrameBlock(new Point2d(ptRes.Value.X, ptRes.Value.Y), frameWidth, frameHeight, tr, db);
tr.Commit();
ed.WriteMessage($"\n图框插入完成! 图框尺寸: {frameWidth:F0} x {frameHeight:F0}");
}
}
catch (System.Exception ex)
{
ed.WriteMessage($"\n手动插入错误: {ex.Message}");
}
}
private PaperSize CalculateFrameSize()
{
double width = 0;
double height = 0;
// 从自定义尺寸获取
if (double.TryParse(tbLength.Text, out double length) &&
double.TryParse(tbWidth.Text, out double w))
{
width = length;
height = w;
}
// 如果自定义尺寸无效,使用选择的图幅尺寸
if (width <= 0 || height <= 0)
{
if (rbA0.Checked && paperSizes.TryGetValue("A0", out PaperSize size0))
{
width = rbHorizontal.Checked ? Math.Max(size0.Width, size0.Height) : Math.Min(size0.Width, size0.Height);
height = rbHorizontal.Checked ? Math.Min(size0.Width, size0.Height) : Math.Max(size0.Width, size0.Height);
}
else if (rbA1.Checked && paperSizes.TryGetValue("A1", out PaperSize size1))
{
width = rbHorizontal.Checked ? Math.Max(size1.Width, size1.Height) : Math.Min(size1.Width, size1.Height);
height = rbHorizontal.Checked ? Math.Min(size1.Width, size1.Height) : Math.Max(size1.Width, size1.Height);
}
else if (rbA2.Checked && paperSizes.TryGetValue("A2", out PaperSize size2))
{
width = rbHorizontal.Checked ? Math.Max(size2.Width, size2.Height) : Math.Min(size2.Width, size2.Height);
height = rbHorizontal.Checked ? Math.Min(size2.Width, size2.Height) : Math.Max(size2.Width, size2.Height);
}
else if (rbA3.Checked && paperSizes.TryGetValue("A3", out PaperSize size3))
{
width = rbHorizontal.Checked ? Math.Max(size3.Width, size3.Height) : Math.Min(size3.Width, size3.Height);
height = rbHorizontal.Checked ? Math.Min(size3.Width, size3.Height) : Math.Max(size3.Width, size3.Height);
}
else if (rbA4.Checked && paperSizes.TryGetValue("A4", out PaperSize size4))
{
width = rbHorizontal.Checked ? Math.Max(size4.Width, size4.Height) : Math.Min(size4.Width, size4.Height);
height = rbHorizontal.Checked ? Math.Min(size4.Width, size4.Height) : Math.Max(size4.Width, size4.Height);
}
else
{
// 默认A2尺寸
width = rbHorizontal.Checked ? 594 : 420;
height = rbHorizontal.Checked ? 420 : 594;
}
}
// 应用加长系数
if (cbExtension.SelectedItem != null &&
cbExtension.SelectedIndex > 0 &&
extensions.TryGetValue(cbExtension.SelectedItem.ToString(), out double extFactor))
{
if (rbHorizontal.Checked)
{
width *= extFactor;
}
else
{
height *= extFactor;
}
}
// 应用比例
double scale = double.TryParse(tbScale.Text, out double s) ? s : 100;
width *= scale;
height *= scale;
// 确保最小尺寸
if (width < 10) width = 420 * scale;
if (height < 10) height = 594 * scale;
return new PaperSize((int)width, (int)height);
}
private void InsertFrameBlock(Point2d basePoint, double width, double height, Transaction tr, Database db)
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
// 获取比例
double scale = double.TryParse(tbScale.Text, out double s) ? s : 100;
// 1. 创建外框(粗线)
using (Polyline outerFrame = new Polyline())
{
outerFrame.AddVertexAt(0, basePoint, 0, 0, 0);
outerFrame.AddVertexAt(1, new Point2d(basePoint.X + width, basePoint.Y), 0, 0, 0);
outerFrame.AddVertexAt(2, new Point2d(basePoint.X + width, basePoint.Y + height), 0, 0, 0);
outerFrame.AddVertexAt(3, new Point2d(basePoint.X, basePoint.Y + height), 0, 0, 0);
outerFrame.Closed = true;
outerFrame.Layer = "0";
outerFrame.ColorIndex = 7; // 白色
outerFrame.LineWeight = LineWeight.LineWeight050; // 粗线
btr.AppendEntity(outerFrame);
tr.AddNewlyCreatedDBObject(outerFrame, true);
}
// 2. 创建内框(细线)
double innerMargin = 5 * scale; // 内边距5mm
using (Polyline innerFrame = new Polyline())
{
innerFrame.AddVertexAt(0, new Point2d(basePoint.X + innerMargin, basePoint.Y + innerMargin), 0, 0, 0);
innerFrame.AddVertexAt(1, new Point2d(basePoint.X + width - innerMargin, basePoint.Y + innerMargin), 0, 0, 0);
innerFrame.AddVertexAt(2, new Point2d(basePoint.X + width - innerMargin, basePoint.Y + height - innerMargin), 0, 0, 0);
innerFrame.AddVertexAt(3, new Point2d(basePoint.X + innerMargin, basePoint.Y + height - innerMargin), 0, 0, 0);
innerFrame.Closed = true;
innerFrame.Layer = "0";
innerFrame.ColorIndex = 7; // 白色
innerFrame.ConstantWidth = 1 * scale; // 1mm线宽
btr.AppendEntity(innerFrame);
tr.AddNewlyCreatedDBObject(innerFrame, true);
}
// 3. 创建底部标题栏区域
if (cbTitleBlock.Checked)
{
CreateTitleBlock(btr, tr, basePoint, width, height, scale);
}
// 4. 添加比例文本到图框右上角
using (DBText scaleText = new DBText())
{
scaleText.Position = new Point3d(basePoint.X + width - 50 * scale, basePoint.Y + height - 20 * scale, 0);
scaleText.Height = 5 * scale;
scaleText.TextString = $"比例 1:{tbScale.Text}";
scaleText.Layer = "0";
scaleText.ColorIndex = 7;
btr.AppendEntity(scaleText);
tr.AddNewlyCreatedDBObject(scaleText, true);
}
// 5. 添加图幅尺寸文本到图框顶部中间
using (DBText sizeText = new DBText())
{
sizeText.Position = new Point3d(basePoint.X + width / 2, basePoint.Y + height - 20 * scale, 0);
sizeText.Height = 5 * scale;
sizeText.HorizontalMode = TextHorizontalMode.TextCenter;
sizeText.VerticalMode = TextVerticalMode.TextBase;
sizeText.AlignmentPoint = new Point3d(basePoint.X + width / 2, basePoint.Y + height - 20 * scale, 0);
sizeText.TextString = $"{width / scale:F0} x {height / scale:F0}";
sizeText.Layer = "0";
sizeText.ColorIndex = 7;
btr.AppendEntity(sizeText);
tr.AddNewlyCreatedDBObject(sizeText, true);
}
}
// 创建标题栏 - 直接在图框内创建,不使用块
private void CreateTitleBlock(BlockTableRecord btr, Transaction tr, Point2d basePoint, double width, double height, double scale)
{
double innerMargin = 5 * scale;
double titleBlockHeight = 40 * scale; // 标题栏高度
double titleBlockWidth = width - 2 * innerMargin; // 标题栏宽度
// 标题栏外框
using (Polyline titleBlockOuter = new Polyline())
{
titleBlockOuter.AddVertexAt(0, new Point2d(basePoint.X + innerMargin, basePoint.Y + innerMargin), 0, 0, 0);
titleBlockOuter.AddVertexAt(1, new Point2d(basePoint.X + innerMargin + titleBlockWidth, basePoint.Y + innerMargin), 0, 0, 0);
titleBlockOuter.AddVertexAt(2, new Point2d(basePoint.X + innerMargin + titleBlockWidth, basePoint.Y + innerMargin + titleBlockHeight), 0, 0, 0);
titleBlockOuter.AddVertexAt(3, new Point2d(basePoint.X + innerMargin, basePoint.Y + innerMargin + titleBlockHeight), 0, 0, 0);
titleBlockOuter.Closed = true;
titleBlockOuter.Layer = "0";
titleBlockOuter.ColorIndex = 7;
titleBlockOuter.LineWeight = LineWeight.LineWeight025;
btr.AppendEntity(titleBlockOuter);
tr.AddNewlyCreatedDBObject(titleBlockOuter, true);
}
// 按照要求的8列布局定义列宽
double[] columnWidths = {
25 * scale, // 第1列
25 * scale, // 第2列
25 * scale, // 第3列
25 * scale, // 第4列
40 * scale, // 第5列
25 * scale, // 第6列
25 * scale, // 第7列
25 * scale // 第8列
};
// 定义行高(4行,平均分配高度)
double rowHeight = titleBlockHeight / 4;
// 创建网格线
CreateTitleBlockGridLines(btr, tr, basePoint, innerMargin, titleBlockWidth, titleBlockHeight, columnWidths, rowHeight, scale);
// 创建标签文本和输入区域
CreateTitleBlockContent(btr, tr, basePoint, innerMargin, titleBlockWidth, titleBlockHeight, columnWidths, rowHeight, scale);
}
// 创建标题栏网格线
private void CreateTitleBlockGridLines(BlockTableRecord btr, Transaction tr, Point2d basePoint, double innerMargin,
double width, double height, double[] columnWidths, double rowHeight, double scale)
{
double startX = basePoint.X + innerMargin;
double startY = basePoint.Y + innerMargin;
// 计算列起始位置
double[] columnStarts = new double[columnWidths.Length + 1];
columnStarts[0] = startX;
for (int i = 0; i < columnWidths.Length; i++)
{
columnStarts[i + 1] = columnStarts[i] + columnWidths[i];
}
// 垂直线
for (int i = 1; i < columnStarts.Length - 1; i++)
{
using (Line line = new Line(
new Point3d(columnStarts[i], startY, 0),
new Point3d(columnStarts[i], startY + height, 0)))
{
line.Layer = "0";
line.ColorIndex = 7;
line.LineWeight = LineWeight.LineWeight000;
btr.AppendEntity(line);
tr.AddNewlyCreatedDBObject(line, true);
}
}
// 水平线
for (int i = 1; i < 4; i++)
{
double yPos = startY + i * rowHeight;
using (Line line = new Line(
new Point3d(startX, yPos, 0),
new Point3d(startX + width, yPos, 0)))
{
line.Layer = "0";
line.ColorIndex = 7;
line.LineWeight = LineWeight.LineWeight000;
btr.AppendEntity(line);
tr.AddNewlyCreatedDBObject(line, true);
}
}
// 擦除合并单元格的线
EraseMergedCellLines(btr, tr, startX, startY, width, height, columnWidths, rowHeight, scale);
}
// 擦除合并单元格的线
private void EraseMergedCellLines(BlockTableRecord btr, Transaction tr, double startX, double startY,
double width, double height, double[] columnWidths, double rowHeight, double scale)
{
// 计算列起始位置
double[] columnStarts = new double[columnWidths.Length + 1];
columnStarts[0] = startX;
for (int i = 0; i < columnWidths.Length; i++)
{
columnStarts[i + 1] = columnStarts[i] + columnWidths[i];
}
// 擦除单位名称至工程名称之间的三格合并线(第2-4列合并)
EraseVerticalLineAtX(btr, tr, columnStarts[2], startY, startY + rowHeight); // 第2列线
EraseVerticalLineAtX(btr, tr, columnStarts[3], startY, startY + rowHeight); // 第3列线
EraseVerticalLineAtX(btr, tr, columnStarts[4], startY, startY + rowHeight); // 第4列线
// 擦除图纸名称三单元格合并线(第5列的第2-4行合并)
EraseHorizontalLineAtY(btr, tr, columnStarts[4], columnStarts[5], startY + rowHeight); // 第2行线
EraseHorizontalLineAtY(btr, tr, columnStarts[4], columnStarts[5], startY + 2 * rowHeight); // 第3行线
EraseHorizontalLineAtY(btr, tr, columnStarts[4], columnStarts[5], startY + 3 * rowHeight); // 第4行线
}
// 擦除指定X位置的垂直线段
private void EraseVerticalLineAtX(BlockTableRecord btr, Transaction tr, double x, double yStart, double yEnd)
{
foreach (ObjectId id in btr)
{
Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
if (ent is Line line)
{
// 检查是否是垂直线且在指定X位置
if (Math.Abs(line.StartPoint.X - line.EndPoint.X) < 0.001 &&
Math.Abs(line.StartPoint.X - x) < 0.001 &&
Math.Abs(line.StartPoint.Y - yStart) < 0.001 &&
Math.Abs(line.EndPoint.Y - yEnd) < 0.001)
{
line.UpgradeOpen();
line.Erase();
break;
}
}
}
}
// 擦除指定Y位置的水平线段
private void EraseHorizontalLineAtY(BlockTableRecord btr, Transaction tr, double xStart, double xEnd, double y)
{
foreach (ObjectId id in btr)
{
Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
if (ent is Line line)
{
// 检查是否是水平线且在指定Y位置
if (Math.Abs(line.StartPoint.Y - line.EndPoint.Y) < 0.001 &&
Math.Abs(line.StartPoint.Y - y) < 0.001 &&
Math.Abs(line.StartPoint.X - xStart) < 0.001 &&
Math.Abs(line.EndPoint.X - xEnd) < 0.001)
{
line.UpgradeOpen();
line.Erase();
break;
}
}
}
}
// 创建标题栏内容
private void CreateTitleBlockContent(BlockTableRecord btr, Transaction tr, Point2d basePoint, double innerMargin,
double width, double height, double[] columnWidths, double rowHeight, double scale)
{
double startX = basePoint.X + innerMargin;
double startY = basePoint.Y + innerMargin;
double textHeight = 3.5 * scale;
// 计算列起始位置
double[] columnStarts = new double[columnWidths.Length + 1];
columnStarts[0] = startX;
for (int i = 0; i < columnWidths.Length; i++)
{
columnStarts[i + 1] = columnStarts[i] + columnWidths[i];
}
// 第一行
CreateText(btr, tr, "单位名称", new Point3d(columnStarts[0] + 2 * scale, startY + rowHeight * 3.5, 0), textHeight);
// 单位名称输入单元格(合并第2-4列)
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[1] + (columnWidths[1] + columnWidths[2] + columnWidths[3]) / 2, startY + rowHeight * 3.5, 0), textHeight);
CreateText(btr, tr, "工程名称", new Point3d(columnStarts[4] + 2 * scale, startY + rowHeight * 3.5, 0), textHeight);
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[5] + columnWidths[5] / 2, startY + rowHeight * 3.5, 0), textHeight);
CreateText(btr, tr, "分部分项", new Point3d(columnStarts[6] + 2 * scale, startY + rowHeight * 3.5, 0), textHeight);
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[7] + columnWidths[7] / 2, startY + rowHeight * 3.5, 0), textHeight);
// 第二行
CreateText(btr, tr, "制图人", new Point3d(columnStarts[0] + 2 * scale, startY + rowHeight * 2.5, 0), textHeight);
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[1] + columnWidths[1] / 2, startY + rowHeight * 2.5, 0), textHeight);
CreateText(btr, tr, "工程负责人", new Point3d(columnStarts[2] + 2 * scale, startY + rowHeight * 2.5, 0), textHeight); // 修复:放在第3列
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[3] + columnWidths[3] / 2, startY + rowHeight * 2.5, 0), textHeight);
// 图纸名称(合并第5列的第2-4行)
CreateText(btr, tr, "图纸名称", new Point3d(columnStarts[4] + 2 * scale, startY + rowHeight * 2, 0), textHeight);
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[5] + columnWidths[5] / 2, startY + rowHeight * 2, 0), textHeight);
CreateText(btr, tr, "图号", new Point3d(columnStarts[6] + 2 * scale, startY + rowHeight * 2.5, 0), textHeight);
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[7] + columnWidths[7] / 2, startY + rowHeight * 2.5, 0), textHeight);
// 第三行
CreateText(btr, tr, "审核人", new Point3d(columnStarts[0] + 2 * scale, startY + rowHeight * 1.5, 0), textHeight);
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[1] + columnWidths[1] / 2, startY + rowHeight * 1.5, 0), textHeight);
CreateText(btr, tr, "专业负责人", new Point3d(columnStarts[2] + 2 * scale, startY + rowHeight * 1.5, 0), textHeight); // 修复:放在第3列
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[3] + columnWidths[3] / 2, startY + rowHeight * 1.5, 0), textHeight);
CreateText(btr, tr, "比例", new Point3d(columnStarts[6] + 2 * scale, startY + rowHeight * 1.5, 0), textHeight);
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[7] + columnWidths[7] / 2, startY + rowHeight * 1.5, 0), textHeight);
// 第四行
CreateText(btr, tr, "审定人", new Point3d(columnStarts[0] + 2 * scale, startY + rowHeight * 0.5, 0), textHeight);
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[1] + columnWidths[1] / 2, startY + rowHeight * 0.5, 0), textHeight);
CreateText(btr, tr, "技术负责人", new Point3d(columnStarts[2] + 2 * scale, startY + rowHeight * 0.5, 0), textHeight); // 修复:放在第3列
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[3] + columnWidths[3] / 2, startY + rowHeight * 0.5, 0), textHeight);
CreateText(btr, tr, "日期", new Point3d(columnStarts[6] + 2 * scale, startY + rowHeight * 0.5, 0), textHeight);
CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[7] + columnWidths[7] / 2, startY + rowHeight * 0.5, 0), textHeight);
}
// 创建文本
private void CreateText(BlockTableRecord btr, Transaction tr, string text, Point3d position, double height)
{
using (DBText dbText = new DBText())
{
dbText.Position = position;
dbText.Height = height;
dbText.TextString = text;
dbText.Layer = "0";
dbText.ColorIndex = 7;
btr.AppendEntity(dbText);
tr.AddNewlyCreatedDBObject(dbText, true);
}
}
// 使用PaperSize替代Size避免命名冲突
private class PaperSize
{
public int Width { get; }
public int Height { get; }
public PaperSize(int width, int height)
{
Width = width;
Height = height;
}
}
}
}
1、插入的图框内框上方改为不显示如“1189x841”和比例1:100
2、标题栏列宽和表格样式修改如下:
下面按A4方向横向插入为例尺寸:
从右向左第1列宽2500mm;第二列宽2000mm;第三列宽4500mm;第四列宽2000mm;第五列宽2500mm;第六列宽2000mm;第七列宽2500mm;第八列宽2000mm;“标题栏”列宽与行高统一1000mm始终不变,“标题栏”随插入的图框大小尺寸自动缩放“标题栏”,“标题栏”顶第一根线宽与内框同线宽,
3、“标题栏”必须自动生成为可编辑的属性,能够双击后弹窗显示“标题栏”属性编辑窗口;窗口布局如下:
第一行:“属性”按钮;“文字选项”按钮
第二行“属性”按钮后:输入框;输入框内分为三列:左列表头“标记”向右第二列表头“提示”,向右第三列表头“值”(标记与提示是“标题栏”已有的名称,“值”列为输入单元格),举例:
标记 提示 值
制图人 制图人 张三
图纸名称 图纸名称 一层平面布置图
第二行“文字选项”按钮后:文字样式:可输可选框;字体大小:可输可选框;
第三行:确认 取消
最新发布