同一行的文本框和文字不能轴对称解决办法

本文介绍了解决注册页面中出生日期输入框的文字上下对齐及与标签轴对称的问题。通过设置CSS属性实现文本框内文字垂直居中显示,并使标签与输入框保持一致的垂直位置。

 今天写注册页面,出生日期,文本框的高度都比平常高了一点,遇到这么个问题,如图:

两个问题:

  1、文本框里头的字靠上;

  2、“年”和“月”跟文本框没有轴对称。

太难看了,下面记录下解决办法:

  1、文本框文字:给文本框添加CSS    style="height:25px; line-height:25px"

  2、文字竖直居中:用<span>框起文字,然后添加CSS样式,同样道理 style=”height:25px; line-height:25px“ 

    注:如果不能到同一行了,每个标签添加float=left就可以了

效果:

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.IO; using System.Reflection; using System.Windows.Forms; using Application = Autodesk.AutoCAD.ApplicationServices.Application; namespace ScaffoldSteelPlugin { public class ScaffoldCommands { // 共享记忆数据(步骤间传递) private static double _memorizedDistance; // 步骤1量取的尺寸 private static List<BeamInfo> _memorizedBeams = new List<BeamInfo>(); // 步骤2记忆的横杆信息 private static Vector3d _memorizedDirection; // 步骤2识别的横杆方向 private static SteelSettings _currentSettings; // 当前方钢设置参数 private static readonly List<string> _beamBlockNames = new List<string> { "ScaffoldPole横杆300mm", "ScaffoldPole横杆600mm", "ScaffoldPole横杆900mm", "ScaffoldPole横杆1200mm", "ScaffoldPole横杆1500mm", "ScaffoldPole横杆1800mm" }; // 支持的横杆图块名列表 private static readonly List<double> _steelStandardLengths = new List<double> { 1000,1500,2000,2500,3000,3500,4000,4500,6000 }; // 方钢标准长度(mm) // 横杆信息类 private class BeamInfo { public Point3d Position { get; set; } public double Rotation { get; set; } public Vector3d Direction { get; set; } public double Length { get; set; } public string BlockName { get; set; } } // 方钢设置参数类 public class SteelSettings { public bool IsUnderSlab { get; set; } // 是否为板下方钢 public bool IsUnderBeam { get; set; } // 是否为梁下方钢 public double Height { get; set; } // 方钢高度 public double Width { get; set; } // 方钢宽度 public string Direction { get; set; } // 布置方向 public string PlacementType { get; set; } // 使用部位 } // 统计信息类 private class SteelStatisticsInfo { public string MaterialName { get; set; } // 材料名称 public string Specification { get; set; } // 规格 public string PlacementType { get; set; } // 使用部位 public double Length { get; set; } // 长度 public int Count { get; set; } // 数量 } /// <summary> /// 显示参数设置窗口 /// </summary> private static bool ShowSettingsDialog() { try { // 创建并显示参数设置窗体 SettingsForm form = new SettingsForm(); DialogResult result = Application.ShowModalDialog(form); if (result == DialogResult.OK) { _currentSettings = form.GetSettings(); return true; } return false; } catch (System.Exception ex) { Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\n显示设置窗口错误:{ex.Message}"); return false; } } /// <summary> /// 主命令:脚手架方钢布置(缩写SP) /// </summary> [CommandMethod("ScaffoldPlace", "SP", CommandFlags.Modal)] public void ScaffoldSteelPlacement() { Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; try { // 显示参数设置窗口 if (!ShowSettingsDialog()) return; // 步骤1:量取尺寸并记忆 if (!Step1_MeasureAndMemorize(ed)) return; // 步骤2:框选横杆、识别方向 if (!Step2_SelectBeamAndMemorize(ed, db)) return; // 步骤3:输入参数并布置方钢 Step3_InputParamsAndPlaceSteel(ed, db); } catch (System.Exception ex) { ed.WriteMessage($"\n插件执行错误:{ex.Message}"); } } /// <summary> /// 方钢统计命令(缩写SS) /// </summary> [CommandMethod("ScaffoldStat", "SS", CommandFlags.Modal)] public void ScaffoldSteelStatistics() { Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; try { ed.WriteMessage("\n=== 方钢统计 ==="); ed.WriteMessage("\n请框选要统计的图块:"); // 创建过滤器,选择方钢双槽钢拖梁图块 TypedValue[] filterList = new TypedValue[] { new TypedValue((int)DxfCode.Start, "INSERT"), new TypedValue((int)DxfCode.BlockName, "*方钢*,*双槽钢拖梁*") }; SelectionFilter filter = new SelectionFilter(filterList); PromptSelectionResult selRes = ed.GetSelection(filter); if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消选择操作"); return; } if (selRes.Value.Count == 0) { ed.WriteMessage("\n未选中任何图块"); return; } // 统计数据 Dictionary<string, SteelStatisticsInfo> steelStatistics = new Dictionary<string, SteelStatisticsInfo>(); using (Transaction tr = db.TransactionManager.StartTransaction()) { foreach (SelectedObject selObj in selRes.Value) { Entity ent = tr.GetObject(selObj.ObjectId, OpenMode.ForRead) as Entity; if (ent is BlockReference br) { if (br.Name.Contains("方钢")) { ProcessSteelStatistics(br, steelStatistics); } else if (br.Name.Contains("双槽钢拖梁")) { ProcessChannelSteelStatistics(br, steelStatistics); } } } tr.Commit(); } if (steelStatistics.Count == 0) { ed.WriteMessage("\n未找到有效的图块"); return; } // 获取插入点 PromptPointResult ptRes = ed.GetPoint("\n指定表格插入点: "); if (ptRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消表格插入"); return; } // 创建统计表格 CreateStatisticsTable(db, ptRes.Value, steelStatistics); ed.WriteMessage($"\n统计完成!共统计{steelStatistics.Count}种规格的材料"); } catch (System.Exception ex) { ed.WriteMessage($"\n统计过程错误:{ex.Message}"); } } // 处理方钢统计 private void ProcessSteelStatistics(BlockReference br, Dictionary<string, SteelStatisticsInfo> steelStatistics) { // 从图层名中提取使用部位长度信息 string layerName = br.Layer; string placementType = "板下方钢"; // 默认值 double lengthInMm = 0; // 从图层名解析使用部位长度 if (layerName.Contains("板下方钢")) { placementType = "板下方钢"; string lengthStr = layerName.Replace("板下方钢", "").Replace("m", ""); if (double.TryParse(lengthStr, out double lengthInMeters)) { lengthInMm = lengthInMeters * 1000; } } else if (layerName.Contains("梁下方钢")) { placementType = "梁下方钢"; string lengthStr = layerName.Replace("梁下方钢", "").Replace("m", ""); if (double.TryParse(lengthStr, out double lengthInMeters)) { lengthInMm = lengthInMeters * 1000; } } // 从扩展数据中获取规格信息 double height = 100; // 默认值 double width = 50; // 默认值 // 读取扩展数据 if (br.XData != null) { ResultBuffer rb = br.XData; TypedValue[] values = rb.AsArray(); for (int i = 0; i < values.Length; i++) { if (values[i].TypeCode == 1040) // 实数类型 { if (height == 100) // 第一个实数是高度 { height = (double)values[i].Value; } else if (width == 50) // 第二个实数是宽度 { width = (double)values[i].Value; } } } } // 如果无法从图层名获取长度,则从块名中提取 if (lengthInMm == 0) { string lengthStr = br.Name.Replace("m方钢", ""); if (double.TryParse(lengthStr, out double lengthInMeters)) { lengthInMm = lengthInMeters * 1000; } } // 创建统计键 - 包含使用部位信息 string statKey = $"方钢_{height}x{width}_{placementType}_{lengthInMm}"; if (steelStatistics.ContainsKey(statKey)) { steelStatistics[statKey].Count++; } else { steelStatistics[statKey] = new SteelStatisticsInfo { MaterialName = "方钢", Specification = $"{height}x{width}", PlacementType = placementType, Length = lengthInMm, Count = 1 }; } } // 处理双槽钢拖梁统计 private void ProcessChannelSteelStatistics(BlockReference br, Dictionary<string, SteelStatisticsInfo> steelStatistics) { // 从块名中提取长度 double lengthInMm = 0; if (br.Name.Contains("1350mm")) { lengthInMm = 1350; } else if (br.Name.Contains("1650mm")) { lengthInMm = 1650; } // 创建统计键 string statKey = $"双槽钢拖梁_10#{lengthInMm}"; if (steelStatistics.ContainsKey(statKey)) { steelStatistics[statKey].Count++; } else { steelStatistics[statKey] = new SteelStatisticsInfo { MaterialName = "双槽钢拖梁", Specification = "10#", PlacementType = "", Length = lengthInMm, Count = 1 }; } } // 创建统计表格方法 private void CreateStatisticsTable(Database db, Point3d insertionPoint, Dictionary<string, SteelStatisticsInfo> steelStatistics) { using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); // 计算行数:标题行 + 表头行 + 数据行 + 说明行 int rowCount = 1 + 1 + steelStatistics.Count + 1; // 标题行+表头行+数据行+说明行 int colCount = 6; // 序号、材料名称、规格、使用部位、长度(mm)、数量统计 Table table = new Table(); table.SetSize(rowCount, colCount); table.Position = insertionPoint; // 设置表格样式 table.SetRowHeight(0, 12); // 标题行高度 for (int i = 1; i < rowCount; i++) { table.SetRowHeight(i, 8); // 其他行高度 } // 设置列宽 table.SetColumnWidth(0, 15); // 序号列 table.SetColumnWidth(1, 30); // 材料名称列 table.SetColumnWidth(2, 25); // 规格列 table.SetColumnWidth(3, 25); // 使用部位列 table.SetColumnWidth(4, 25); // 长度列 table.SetColumnWidth(5, 20); // 数量统计列 // 设置标题行 - 合并所有列 table.MergeCells(CellRange.Create(table, 0, 0, 0, colCount - 1)); table.SetTextHeight(0, 0, 5); table.SetAlignment(0, 0, CellAlignment.MiddleCenter); table.SetTextString(0, 0, "材料统计表"); // 设置表头行 string[] headers = { "序号", "材料名称", "规格", "使用部位", "长度(mm)", "数量统计" }; for (int col = 0; col < colCount; col++) { table.SetTextHeight(1, col, 3.5); table.SetAlignment(1, col, CellAlignment.MiddleCenter); table.SetTextString(1, col, headers[col]); } // 填充数据行 int rowIndex = 2; int serialNumber = 1; // 直接统计所有材料,不添加分类标题 foreach (var item in steelStatistics.Values) { FillTableRow(table, rowIndex, serialNumber, item); serialNumber++; rowIndex++; } // 添加说明行 - 合并所有列 table.MergeCells(CellRange.Create(table, rowIndex, 0, rowIndex, colCount - 1)); table.SetTextHeight(rowIndex, 0, 3.0); // 减小说明文字大小 table.SetAlignment(rowIndex, 0, CellAlignment.MiddleLeft); table.SetTextString(rowIndex, 0, "说明:本表统计的材料用量属预估量,具体实际用量按施工用量为准。"); // 将表格添加到模型空间 btr.AppendEntity(table); tr.AddNewlyCreatedDBObject(table, true); tr.Commit(); } } // 辅助方法:填充表格行 private void FillTableRow(Table table, int rowIndex, int serialNumber, SteelStatisticsInfo info) { // 序号列 table.SetTextHeight(rowIndex, 0, 3); table.SetAlignment(rowIndex, 0, CellAlignment.MiddleCenter); table.SetTextString(rowIndex, 0, serialNumber.ToString()); // 材料名称列 - 居中对齐 table.SetTextHeight(rowIndex, 1, 3); table.SetAlignment(rowIndex, 1, CellAlignment.MiddleCenter); table.SetTextString(rowIndex, 1, info.MaterialName); // 规格列 table.SetTextHeight(rowIndex, 2, 3); table.SetAlignment(rowIndex, 2, CellAlignment.MiddleCenter); table.SetTextString(rowIndex, 2, info.Specification); // 使用部位列 table.SetTextHeight(rowIndex, 3, 3); table.SetAlignment(rowIndex, 3, CellAlignment.MiddleCenter); table.SetTextString(rowIndex, 3, info.PlacementType); // 长度列 table.SetTextHeight(rowIndex, 4, 3); table.SetAlignment(rowIndex, 4, CellAlignment.MiddleCenter); table.SetTextString(rowIndex, 4, info.Length.ToString()); // 数量统计列 table.SetTextHeight(rowIndex, 5, 3); table.SetAlignment(rowIndex, 5, CellAlignment.MiddleCenter); table.SetTextString(rowIndex, 5, info.Count.ToString()); } #region 步骤1:量取尺寸并记忆 private bool Step1_MeasureAndMemorize(Editor ed) { ed.WriteMessage("\n=== 步骤1:量取尺寸 ==="); PromptPointOptions ptOpts1 = new PromptPointOptions("\n指定第一点"); PromptPointResult pt1Res = ed.GetPoint(ptOpts1); if (pt1Res.Status != PromptStatus.OK) { ed.WriteMessage("\n取消量取操作"); return false; } PromptDistanceOptions distOpts = new PromptDistanceOptions("\n指定第二点(量取尺寸)"); distOpts.UseBasePoint = true; distOpts.BasePoint = pt1Res.Value; PromptDoubleResult distRes = ed.GetDistance(distOpts); if (distRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消量取操作"); return false; } _memorizedDistance = distRes.Value; ed.WriteMessage($"\n量取尺寸记忆成功:{_memorizedDistance:F2}mm"); return true; } #endregion #region 步骤2:框选横杆、识别方向 private bool Step2_SelectBeamAndMemorize(Editor ed, Database db) { ed.WriteMessage("\n\n=== 步骤2:识别横杆 ==="); // 创建过滤器,只选择横杆图块 TypedValue[] filterList = new TypedValue[] { new TypedValue((int)DxfCode.Start, "INSERT"), new TypedValue((int)DxfCode.BlockName, "ScaffoldPole横杆*") }; SelectionFilter filter = new SelectionFilter(filterList); // 允许用户多次尝试选择 int maxAttempts = 3; for (int attempt = 1; attempt <= maxAttempts; attempt++) { ed.WriteMessage($"\n\n请框选横杆图块 (尝试 {attempt}/{maxAttempts}):"); PromptSelectionResult selRes = ed.GetSelection(filter); if (selRes.Status != PromptStatus.OK) { if (selRes.Status == PromptStatus.Cancel) { ed.WriteMessage("\n取消选择操作"); return false; } ed.WriteMessage("\n未选中任何对象,请重试"); continue; } if (selRes.Value.Count == 0) { ed.WriteMessage("\n未选中任何对象,请重试"); continue; } // 在事务中检查选中的对象 using (Transaction tr = db.TransactionManager.StartTransaction()) { // 清空之前的横杆信息 _memorizedBeams.Clear(); // 查找所有有效的横杆图块 foreach (SelectedObject selObj in selRes.Value) { Entity ent = tr.GetObject(selObj.ObjectId, OpenMode.ForRead) as Entity; if (ent is BlockReference) { BlockReference br = ent as BlockReference; if (_beamBlockNames.Contains(br.Name)) { // 使用旋转角度计算方向,而不是包围盒 Vector3d direction = Vector3d.XAxis.RotateBy(br.Rotation, Vector3d.ZAxis); // 从块名中提取长度 string lengthStr = br.Name.Replace("ScaffoldPole横杆", "").Replace("mm", ""); double length = 0; double.TryParse(lengthStr, out length); _memorizedBeams.Add(new BeamInfo { Position = br.Position, Rotation = br.Rotation, Direction = direction, Length = length, BlockName = br.Name }); // 记录第一根横杆的方向作为参考方向 if (_memorizedBeams.Count == 1) { _memorizedDirection = direction; } } } } if (_memorizedBeams.Count == 0) { ed.WriteMessage("\n未选中有效横杆图块,请重试"); continue; } ed.WriteMessage($"\n成功识别 {_memorizedBeams.Count} 根横杆"); tr.Commit(); return true; } } ed.WriteMessage($"\n经过{maxAttempts}次尝试后仍未选中有效横杆,命令终止"); return false; } #endregion #region 步骤3:输入参数并布置方钢 private void Step3_InputParamsAndPlaceSteel(Editor ed, Database db) { ed.WriteMessage("\n\n=== 步骤3:布置方钢 ==="); // 首先获取布置基点 PromptPointOptions basePtOpts = new PromptPointOptions("\n指定布置基点"); PromptPointResult basePtRes = ed.GetPoint(basePtOpts); if (basePtRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消布置操作"); return; } Point3d referencePoint = basePtRes.Value; using (Transaction tr = db.TransactionManager.StartTransaction()) { try { // 1. 输入布置数量(使用整数选择) PromptIntegerOptions countOpts = new PromptIntegerOptions("\n布置数量 [1(单根)/2(双拼)] "); countOpts.AllowZero = false; countOpts.AllowNegative = false; countOpts.LowerLimit = 1; countOpts.UpperLimit = 2; countOpts.DefaultValue = 1; PromptIntegerResult countRes = ed.GetInteger(countOpts); if (countRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消布置操作"); return; } int placementCount = countRes.Value; string placementType = (placementCount == 1) ? "单根" : "双拼"; // 2. 计算推荐的方钢长度 double recommendedLength = CalculateRecommendedSteelLength(_memorizedDistance); // 3. 输入方钢长度(使用循环确保输入在有效范围内) PromptDoubleOptions lenOpts = new PromptDoubleOptions($"\n(标准规格:1m,1.5m,2m,2.5m,3m,3.5m,4m,4.5m,6m)输入方钢长(mm)"); lenOpts.AllowNegative = false; lenOpts.DefaultValue = recommendedLength; // 设置默认值为推荐长度 lenOpts.UseDefaultValue = true; // 使用默认值 PromptDoubleResult lenRes = ed.GetDouble(lenOpts); if (lenRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消布置操作"); return; } double steelLength = lenRes.Value; // 检查输入是否在有效范围内 if (steelLength < 500 || steelLength > 10000) { ed.WriteMessage("\n输入长度必须在500mm到10000mm之间,请重新输入。"); // 这里可以添加重新输入的逻辑,但为了简化,我们直接使用推荐长度 steelLength = recommendedLength; ed.WriteMessage($"\n已自动使用推荐长度:{steelLength}mm"); } if (!_steelStandardLengths.Contains(steelLength)) { ed.WriteMessage($"\n注意:输入长度{steelLength}mm非标准规格,将按输入值拉伸"); } // 4. 输入正负偏移值 PromptDoubleOptions offsetOpts = new PromptDoubleOptions("\n输入基点偏移值(mm,正值沿横杆方向,负值反向)"); PromptDoubleResult offsetRes = ed.GetDouble(offsetOpts); if (offsetRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消布置操作"); return; } double offsetValue = offsetRes.Value; // 5. 生成块名 string steelBlockName = GenerateSteelBlockName(steelLength); // 6. 加载方钢图块 if (!LoadSteelBlock(db, tr, steelBlockName, steelLength)) { ed.WriteMessage("\n方钢图块加载失败,终止布置"); return; } // 7. 创建图层(如果不存在) string layerName = $"{_currentSettings.PlacementType}{steelLength / 1000}m"; CreateLayerIfNotExists(db, tr, layerName); // 8. 计算所有横杆的插入点,确保端头对齐 List<Point3d> insertionPoints = new List<Point3d>(); // 首先计算参考点在横杆方向上的投影 double referenceProjection = 0; if (_memorizedBeams.Count > 0) { Vector3d toReference = referencePoint - _memorizedBeams[0].Position; referenceProjection = toReference.DotProduct(_memorizedDirection); } // 计算所有横杆的插入点 foreach (BeamInfo beam in _memorizedBeams) { // 计算横杆到参考点的投影距离 Vector3d toReference = referencePoint - beam.Position; double projection = toReference.DotProduct(_memorizedDirection); // 计算实际插入点,应用偏移值 Point3d actualInsertPoint = beam.Position + _memorizedDirection * (referenceProjection + offsetValue); insertionPoints.Add(actualInsertPoint); } // 9. 为每根横杆布置方钢 int placedCount = 0; for (int i = 0; i < _memorizedBeams.Count; i++) { BeamInfo beam = _memorizedBeams[i]; Point3d actualInsertPoint = insertionPoints[i]; double scaleFactor = steelLength / 1000.0; // 修正:正确的缩放因子计算 double rotationAngle = beam.Rotation; // 根据设置的方向调整旋转角度 - 修正后的逻辑 switch (_currentSettings.Direction) { case "朝右": // 不作任何改变 break; case "朝左": // 旋转180度 rotationAngle += Math.PI; break; case "朝上": // 旋转90度 rotationAngle +=0/ Math.PI / 3; break; case "朝下": // 旋转270度(即-90度) rotationAngle += 3 * Math.PI / 3; break; } // 布置方钢 if (placementCount == 1) // 单根 { // 修正:单根布置时,方钢居中在横杆上 InsertSteelBlock(tr, db, steelBlockName, actualInsertPoint, scaleFactor, rotationAngle, beam.Direction, layerName, steelLength, placementCount, 0); placedCount++; } else if (placementCount == 2) // 双拼 { // 修正:双拼布置时,两根方钢对称布置在横杆两侧 Vector3d verticalDir = beam.Direction.RotateBy(Math.PI / 2, Vector3d.ZAxis); double steelWidth = _currentSettings.Width; // 第一根方钢(上方/右侧) Point3d pt1 = actualInsertPoint + verticalDir * (steelWidth / 2); InsertSteelBlock(tr, db, steelBlockName, pt1, scaleFactor, rotationAngle, beam.Direction, layerName, steelLength, placementCount, 1); // 第二根方钢(下方/左侧) Point3d pt2 = actualInsertPoint - verticalDir * (steelWidth / 2); InsertSteelBlock(tr, db, steelBlockName, pt2, scaleFactor, rotationAngle, beam.Direction, layerName, steelLength, placementCount, 2); placedCount += 2; } } ed.WriteMessage($"\n方钢布置完成!共布置{placedCount}根方钢,长度{steelLength}mm,偏移{offsetValue}mm"); tr.Commit(); } catch (System.Exception ex) { ed.WriteMessage($"\n布置过程错误:{ex.Message}"); tr.Abort(); } } } #endregion #region 辅助方法:计算推荐的方钢长度 private double CalculateRecommendedSteelLength(double measuredDistance) { // 如果量取尺寸大于6000mm,则不扣减,默认使用6000mm if (measuredDistance > 6000) { return 6000; } // 否则扣减350mm double deductedDistance = measuredDistance - 350; // 在标准规格中找到最接近但不大于扣减后尺寸的值 double recommendedLength = 1000; // 默认最小值 foreach (double standardLength in _steelStandardLengths) { if (standardLength <= deductedDistance && standardLength > recommendedLength) { recommendedLength = standardLength; } } return recommendedLength; } #endregion #region 双槽钢拖梁布置命令(缩写SC1) [CommandMethod("ScaffoldChannel", "SC1", CommandFlags.Modal)] public void ScaffoldChannelSteelPlacement() { Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; try { ed.WriteMessage("\n=== 双槽钢/梁下方钢布置 ==="); // 框选横杆 if (!Step2_SelectBeamAndMemorize(ed, db)) return; // 选择布置类型 PromptKeywordOptions typeOpts = new PromptKeywordOptions("\n请选择布置类型 [<1>梁下方钢/<2>双槽钢拖梁]"); typeOpts.Keywords.Add("1"); typeOpts.Keywords.Add("2"); typeOpts.Keywords.Default = "1"; typeOpts.AllowNone = false; PromptResult typeRes = ed.GetKeywords(typeOpts); if (typeRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消布置操作"); return; } string selectedType = typeRes.StringResult; if (selectedType == "1") { // 梁下方钢布置逻辑 // 1. 输入布置数量 PromptIntegerOptions countOpts = new PromptIntegerOptions("\n布置数量 [1(单根)/2(双拼)] "); countOpts.AllowZero = false; countOpts.AllowNegative = false; countOpts.LowerLimit = 1; countOpts.UpperLimit = 2; countOpts.DefaultValue = 1; PromptIntegerResult countRes = ed.GetInteger(countOpts); if (countRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消布置操作"); return; } int placementCount = countRes.Value; // 2. 输入方钢长度 PromptDoubleOptions lenOpts = new PromptDoubleOptions($"\n输入方钢长度(mm)"); lenOpts.AllowNegative = false; lenOpts.DefaultValue = 1000; // 默认1000mm lenOpts.UseDefaultValue = true; PromptDoubleResult lenRes = ed.GetDouble(lenOpts); if (lenRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消布置操作"); return; } double steelLength = lenRes.Value; // 3. 加载梁下方钢图块 string blockName = $"ScaffoldPole方钢{steelLength}mm"; using (Transaction tr = db.TransactionManager.StartTransaction()) { // 加载图块 if (!LoadSteelBlock(db, tr, blockName, steelLength)) { ed.WriteMessage("\n梁下方钢图块加载失败,终止布置"); return; } // 创建图层(如果不存在) string layerName = $"梁下方钢{steelLength / 1000}m"; CreateLayerIfNotExists(db, tr, layerName); // 布置梁下方钢 int placedCount = 0; BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); foreach (BeamInfo beam in _memorizedBeams) { // 计算插入点(横杆的中心点) Point3d insertPoint = beam.Position; double rotationAngle = beam.Rotation; // 计算缩放比例 double scaleFactor = steelLength / 1000.0; // 基础图块长度为1000mm if (placementCount == 1) // 单根 { // 插入梁下方钢图块 BlockReference steelRef = new BlockReference(insertPoint, bt[blockName]); steelRef.Rotation = rotationAngle; steelRef.ScaleFactors = new Scale3d(scaleFactor, 1, 1); // 只拉伸长度,宽度不变 steelRef.Layer = layerName; steelRef.ColorIndex = 1; // 使用不同颜色区分 btr.AppendEntity(steelRef); tr.AddNewlyCreatedDBObject(steelRef, true); placedCount++; } else if (placementCount == 2) // 双拼 { Vector3d verticalDir = beam.Direction.RotateBy(Math.PI / 2, Vector3d.ZAxis); double steelWidth = 50; // 方钢宽度50mm // 第一根方钢(上方/右侧) Point3d pt1 = insertPoint + verticalDir * (steelWidth / 2); BlockReference steelRef1 = new BlockReference(pt1, bt[blockName]); steelRef1.Rotation = rotationAngle; steelRef1.ScaleFactors = new Scale3d(scaleFactor, 1, 1); steelRef1.Layer = layerName; steelRef1.ColorIndex = 1; // 第二根方钢(下方/左侧) Point3d pt2 = insertPoint - verticalDir * (steelWidth / 2); BlockReference steelRef2 = new BlockReference(pt2, bt[blockName]); steelRef2.Rotation = rotationAngle; steelRef2.ScaleFactors = new Scale3d(scaleFactor, 1, 1); steelRef2.Layer = layerName; steelRef2.ColorIndex = 1; btr.AppendEntity(steelRef1); tr.AddNewlyCreatedDBObject(steelRef1, true); btr.AppendEntity(steelRef2); tr.AddNewlyCreatedDBObject(steelRef2, true); placedCount += 2; } } ed.WriteMessage($"\n梁下方钢布置完成!共布置{placedCount}根方钢,长度{steelLength}mm"); tr.Commit(); } } else // 双槽钢拖梁 { // 选择双槽钢拖梁长度 PromptKeywordOptions lengthOpts = new PromptKeywordOptions("\n请选择双槽钢拖梁长度"); lengthOpts.Keywords.Add("1350mm"); lengthOpts.Keywords.Add("1650mm"); lengthOpts.Keywords.Default = "1350mm"; lengthOpts.AllowNone = false; PromptResult lengthRes = ed.GetKeywords(lengthOpts); if (lengthRes.Status != PromptStatus.OK) { ed.WriteMessage("\n取消布置操作"); return; } string selectedLength = lengthRes.StringResult; double channelLength = selectedLength == "1350mm" ? 1350 : 1650; string blockName = $"ScaffoldPole双槽钢拖梁{selectedLength}"; using (Transaction tr = db.TransactionManager.StartTransaction()) { // 加载双槽钢拖梁图块 if (!LoadChannelSteelBlock(db, tr, blockName, channelLength)) { ed.WriteMessage("\n双槽钢拖梁图块加载失败,终止布置"); return; } // 创建图层(如果不存在) string layerName = $"双槽钢拖梁{channelLength / 1000}m"; CreateLayerIfNotExists(db, tr, layerName); // 布置双槽钢拖梁 int placedCount = 0; BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); foreach (BeamInfo beam in _memorizedBeams) { // 计算双槽钢拖梁的插入点(横杆的中心点) Point3d insertPoint = beam.Position; // 使用横杆的旋转角度,使双槽钢拖梁与横杆平行 double rotationAngle = beam.Rotation; // 插入双槽钢拖梁图块 BlockReference channelRef = new BlockReference(insertPoint, bt[blockName]); channelRef.Rotation = rotationAngle; channelRef.Layer = layerName; channelRef.ColorIndex = 3; // 使用不同颜色区分 btr.AppendEntity(channelRef); tr.AddNewlyCreatedDBObject(channelRef, true); placedCount++; } ed.WriteMessage($"\n双槽钢拖梁布置完成!共布置{placedCount}根双槽钢拖梁,长度{channelLength}mm"); tr.Commit(); } } } catch (System.Exception ex) { ed.WriteMessage($"\n布置过程错误:{ex.Message}"); } } #endregion #region 辅助方法:生成方钢块名 private string GenerateSteelBlockName(double steelLength) { // 将毫米转换为米,并保留一位小数 double lengthInMeters = steelLength / 1000.0; return $"{lengthInMeters:F1}m方钢"; } #endregion #region 辅助方法:加载方钢图块(已删除文字标注) private bool LoadSteelBlock(Database db, Transaction tr, string blockName, double length) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); if (bt.Has(blockName)) return true; try { bt.UpgradeOpen(); BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; ObjectId blockId = bt.Add(btr); tr.AddNewlyCreatedDBObject(btr, true); double halfWidth = _currentSettings.Width / 2; // 1. 创建方钢几何图形 using (Polyline steelPolyline = new Polyline()) { steelPolyline.AddVertexAt(0, new Point2d(0, -halfWidth), 0, 0, 0); steelPolyline.AddVertexAt(1, new Point2d(length, -halfWidth), 0, 0, 0); steelPolyline.AddVertexAt(2, new Point2d(length, halfWidth), 0, 0, 0); steelPolyline.AddVertexAt(3, new Point2d(0, halfWidth), 0, 0, 0); steelPolyline.Closed = true; steelPolyline.ColorIndex = 2; // 黄色 btr.AppendEntity(steelPolyline); tr.AddNewlyCreatedDBObject(steelPolyline, true); } // 注意:已删除文字标注部分,不再创建DBText对象 bt.DowngradeOpen(); Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; ed.WriteMessage($"\n创建图块 '{blockName}',长度: {length}mm,图块原点在方钢中点"); return true; } catch (System.Exception ex) { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; ed.WriteMessage($"\n创建方钢图块时出错:{ex.Message}"); return false; } } #endregion #region 辅助方法:插入方钢图块 - 修正基点问题 private void InsertSteelBlock(Transaction tr, Database db, string blockName, Point3d insertPt, double rotation, Vector3d direction, string layerName, double steelLength, int placementCount, int positionIndex) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); BlockReference steelRef = new BlockReference(insertPt, bt[blockName]); // 修正:图块原点在左端点,所以不需要额外的偏移计算 // 只需要设置旋转角度缩放因子 double widthScale = _currentSettings.Width / 50.0; // 默认宽度为50mm steelRef.ScaleFactors = new Scale3d(1, widthScale, 1); steelRef.Rotation = rotation; steelRef.ColorIndex = 2; // 设置图层 steelRef.Layer = layerName; // 添加扩展数据,记录规格使用部位信息 AddXData(tr, steelRef, _currentSettings.Height, _currentSettings.Width, _currentSettings.PlacementType, steelLength); btr.AppendEntity(steelRef); tr.AddNewlyCreatedDBObject(steelRef, true); } #endregion #region 辅助方法:加载双槽钢拖梁图块 private bool LoadChannelSteelBlock(Database db, Transaction tr, string blockName, double length) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); // 检查是否已存在同名块 if (bt.Has(blockName)) { return true; } // 创建新的双槽钢拖梁图块定义 try { bt.UpgradeOpen(); // 创建新的块表记录 BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; // 将新块添加到块表 ObjectId blockId = bt.Add(btr); tr.AddNewlyCreatedDBObject(btr, true); // 创建双槽钢拖梁的几何图形(两个C型槽钢) double channelHeight = 100; // 槽钢高度 double channelWidth = 48; // 槽钢宽度 double flangeThickness = 8; // 翼缘厚度 double webThickness = 5; // 腹板厚度 // 第一个槽钢 using (Polyline channel1 = CreateChannelProfile(-length / 2, 0, length, channelHeight, channelWidth, flangeThickness, webThickness)) { channel1.ColorIndex = 1; // 红色 btr.AppendEntity(channel1); tr.AddNewlyCreatedDBObject(channel1, true); } // 第二个槽钢(与第一个并排) using (Polyline channel2 = CreateChannelProfile(-length / 2, channelWidth + 10, length, channelHeight, channelWidth, flangeThickness, webThickness)) { channel2.ColorIndex = 1; // 红色 btr.AppendEntity(channel2); tr.AddNewlyCreatedDBObject(channel2, true); } // 添加文字标注 using (DBText text = new DBText()) { text.TextString = $"双槽钢拖梁 {length}mm"; text.Position = new Point3d(0, channelWidth * 2 + 20, 0); text.Height = 15; text.HorizontalMode = TextHorizontalMode.TextCenter; text.VerticalMode = TextVerticalMode.TextBase; text.ColorIndex = 3; // 绿色 btr.AppendEntity(text); tr.AddNewlyCreatedDBObject(text, true); } bt.DowngradeOpen(); return true; } catch (System.Exception ex) { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; ed.WriteMessage($"\n创建双槽钢拖梁图块时出错:{ex.Message}"); return false; } } #endregion #region 辅助方法:创建槽钢轮廓 private Polyline CreateChannelProfile(double startX, double startY, double length, double height, double width, double flangeThickness, double webThickness) { Polyline channel = new Polyline(); // 创建C型槽钢轮廓 channel.AddVertexAt(0, new Point2d(startX, startY), 0, 0, 0); channel.AddVertexAt(1, new Point2d(startX + length, startY), 0, 0, 0); channel.AddVertexAt(2, new Point2d(startX + length, startY + flangeThickness), 0, 0, 0); channel.AddVertexAt(3, new Point2d(startX + webThickness, startY + flangeThickness), 0, 0, 0); channel.AddVertexAt(4, new Point2d(startX + webThickness, startY + height - flangeThickness), 0, 0, 0); channel.AddVertexAt(5, new Point2d(startX + length, startY + height - flangeThickness), 0, 0, 0); channel.AddVertexAt(6, new Point2d(startX + length, startY + height), 0, 0, 0); channel.AddVertexAt(7, new Point2d(startX, startY + height), 0, 0, 0); channel.AddVertexAt(8, new Point2d(startX, startY + height - flangeThickness), 0, 0, 0); channel.AddVertexAt(9, new Point2d(startX + width - webThickness, startY + height - flangeThickness), 0, 0, 0); channel.AddVertexAt(10, new Point2d(startX + width - webThickness, startY + flangeThickness), 0, 0, 0); channel.AddVertexAt(11, new Point2d(startX, startY + flangeThickness), 0, 0, 0); channel.Closed = true; return channel; } #endregion #region 辅助方法:创建图层(如果不存在) private void CreateLayerIfNotExists(Database db, Transaction tr, string layerName) { LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead); if (!lt.Has(layerName)) { lt.UpgradeOpen(); LayerTableRecord ltr = new LayerTableRecord(); ltr.Name = layerName; lt.Add(ltr); tr.AddNewlyCreatedDBObject(ltr, true); lt.DowngradeOpen(); } } #endregion #region 辅助方法:插入方钢图块 - 修正版本 private void InsertSteelBlock(Transaction tr, Database db, string blockName, Point3d insertPt, double scale, double rotation, Vector3d direction, string layerName, double steelLength, int placementCount, int positionIndex) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); BlockReference steelRef = new BlockReference(insertPt, bt[blockName]); // 修正:正确的缩放因子计算 // 由于图块现在以原点为中心创建,缩放因子应该是1(不缩放),因为长度已经在创建图块时确定了 // 但我们仍然使用缩放来调整宽度,如果需要的话 double widthScale = _currentSettings.Width / 50.0; // 默认宽度为50mm steelRef.ScaleFactors = new Scale3d(1, widthScale, 1); // 修正:x方向缩放为1,因为长度已在图块创建时确定 steelRef.Rotation = rotation; steelRef.ColorIndex = 2; // 设置图层 steelRef.Layer = layerName; // 添加扩展数据,记录规格使用部位信息 AddXData(tr, steelRef, _currentSettings.Height, _currentSettings.Width, _currentSettings.PlacementType, steelLength); btr.AppendEntity(steelRef); tr.AddNewlyCreatedDBObject(steelRef, true); } #endregion #region 辅助方法:添加扩展数据 private void AddXData(Transaction tr, BlockReference blockRef, double height, double width, string placementType, double steelLength) { try { // 首先确保应用程序名称已注册 RegAppTable rat = (RegAppTable)tr.GetObject(blockRef.Database.RegAppTableId, OpenMode.ForRead); if (!rat.Has("SCAFFOLD_STEEL")) { rat.UpgradeOpen(); RegAppTableRecord ratr = new RegAppTableRecord(); ratr.Name = "SCAFFOLD_STEEL"; rat.Add(ratr); tr.AddNewlyCreatedDBObject(ratr, true); rat.DowngradeOpen(); } // 创建扩展数据 ResultBuffer rb = new ResultBuffer(); // 添加应用程序名称 rb.Add(new TypedValue(1001, "SCAFFOLD_STEEL")); // 添加高度信息 rb.Add(new TypedValue(1040, height)); // 添加宽度信息 rb.Add(new TypedValue(1040, width)); // 添加使用部位信息 rb.Add(new TypedValue(1000, placementType)); // 添加长度信息 rb.Add(new TypedValue(1040, steelLength)); // 将扩展数据附加到图块 blockRef.XData = rb; } catch (System.Exception ex) { // 扩展数据设置失败不影响主要功能 Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; ed.WriteMessage($"\n设置扩展数据时出错:{ex.Message}"); } } #endregion } // 参数设置窗体 public class SettingsForm : Form { private RadioButton radioUnderSlab; private RadioButton radioUnderBeam; private TextBox textBoxHeight; private TextBox textBoxWidth; private ComboBox comboBoxDirection; private Button buttonOK; private Button buttonCancel; public SettingsForm() { InitializeComponent(); } private void InitializeComponent() { this.Text = "方钢布置参数设置"; this.Size = new System.Drawing.Size(300, 250); this.StartPosition = FormStartPosition.CenterScreen; this.FormBorderStyle = FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; // 板下方钢布置单选按钮 radioUnderSlab = new RadioButton(); radioUnderSlab.Text = "板下方钢布置"; radioUnderSlab.Location = new System.Drawing.Point(20, 20); radioUnderSlab.Size = new System.Drawing.Size(120, 20); radioUnderSlab.Checked = true; radioUnderSlab.CheckedChanged += RadioUnderSlab_CheckedChanged; this.Controls.Add(radioUnderSlab); // 梁下方钢布置单选按钮 radioUnderBeam = new RadioButton(); radioUnderBeam.Text = "梁下方钢布置"; radioUnderBeam.Location = new System.Drawing.Point(20, 50); radioUnderBeam.Size = new System.Drawing.Size(120, 20); radioUnderBeam.CheckedChanged += RadioUnderBeam_CheckedChanged; this.Controls.Add(radioUnderBeam); // 高度标签文本框 Label labelHeight = new Label(); labelHeight.Text = "高:"; labelHeight.Location = new System.Drawing.Point(40, 80); labelHeight.Size = new System.Drawing.Size(30, 20); this.Controls.Add(labelHeight); textBoxHeight = new TextBox(); textBoxHeight.Location = new System.Drawing.Point(70, 80); textBoxHeight.Size = new System.Drawing.Size(60, 20); textBoxHeight.Text = "100"; this.Controls.Add(textBoxHeight); // 宽度标签文本框 Label labelWidth = new Label(); labelWidth.Text = "宽:"; labelWidth.Location = new System.Drawing.Point(140, 80); labelWidth.Size = new System.Drawing.Size(30, 20); this.Controls.Add(labelWidth); textBoxWidth = new TextBox(); textBoxWidth.Location = new System.Drawing.Point(170, 80); textBoxWidth.Size = new System.Drawing.Size(60, 20); textBoxWidth.Text = "50"; this.Controls.Add(textBoxWidth); // 布置方向标签下拉框 Label labelDirection = new Label(); labelDirection.Text = "布置方向:"; labelDirection.Location = new System.Drawing.Point(40, 110); labelDirection.Size = new System.Drawing.Size(80, 20); this.Controls.Add(labelDirection); comboBoxDirection = new ComboBox(); comboBoxDirection.Location = new System.Drawing.Point(120, 110); comboBoxDirection.Size = new System.Drawing.Size(100, 20); comboBoxDirection.Items.AddRange(new object[] { "朝上", "朝下", "朝左", "朝右" }); comboBoxDirection.SelectedIndex = 0; this.Controls.Add(comboBoxDirection); // 确定按钮 buttonOK = new Button(); buttonOK.Text = "开始布置"; buttonOK.Location = new System.Drawing.Point(50, 150); buttonOK.Size = new System.Drawing.Size(80, 25); buttonOK.DialogResult = DialogResult.OK; this.Controls.Add(buttonOK); // 取消按钮 buttonCancel = new Button(); buttonCancel.Text = "取消"; buttonCancel.Location = new System.Drawing.Point(150, 150); buttonCancel.Size = new System.Drawing.Size(80, 25); buttonCancel.DialogResult = DialogResult.Cancel; this.Controls.Add(buttonCancel); // 初始化状态 UpdateControlsState(); } private void RadioUnderSlab_CheckedChanged(object sender, EventArgs e) { if (radioUnderSlab.Checked) { UpdateControlsState(); } } private void RadioUnderBeam_CheckedChanged(object sender, EventArgs e) { if (radioUnderBeam.Checked) { UpdateControlsState(); } } private void UpdateControlsState() { // 根据选择更新控件状态 bool isUnderSlab = radioUnderSlab.Checked; // 这里可以根据需要添加更多逻辑 } public ScaffoldSteelPlugin.ScaffoldCommands.SteelSettings GetSettings() { return new ScaffoldSteelPlugin.ScaffoldCommands.SteelSettings { IsUnderSlab = radioUnderSlab.Checked, IsUnderBeam = radioUnderBeam.Checked, Height = double.Parse(textBoxHeight.Text), Width = double.Parse(textBoxWidth.Text), Direction = comboBoxDirection.SelectedItem.ToString(), PlacementType = radioUnderSlab.Checked ? "板下方钢" : "梁下方钢" }; } } } "SP"方钢布置时自动在方钢的中间标注尺寸,标注样式为:50x100x3方钢*m
10-01
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值