Ref out keywords

本文深入探讨了C#中参数的传递方式,包括按值传递和按引用传递的区别,并介绍了ref和out关键字的使用方法及注意事项。此外,还讨论了方法重载的概念及其在C#中的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ref parameters
Passing variables by value is the default. We can, however, force value parameters to be passed by reference.
To do so, we use the ref keyword. If a parameter is passed to a method, and if the input argument
for that method is prefixed with the ref keyword, then any changes that the method makes to the variable
will affect the value of the original object:
static void SomeFunction(int[] ints, ref int i)
{
ints[0] = 100;
i = 100; // the change to i will persist after SomeFunction() exits
}
We will also need to add the ref keyword when we invoke the method:
SomeFunction(ints, ref i);
90
Chapter 3
Adding the ref keyword in C# serves the same purpose as using the & syntax in C++ to specify passing
by reference. However, C# makes the behavior more explicit (thus hopefully preventing bugs) by requiring
the use of the ref keyword when invoking the method.
Finally, it is also important to understand that C# continues to apply initialization requirements to
parameters passed to methods. Any variable must be initialized before it is passed into a method,
whether it is passed in by value or reference.
out parameters
In C-style languages, it is common for functions to be able to output more than one value from a single
routine. This is accomplished using output parameters, by assigning the output values to variables that
have been passed to the method by reference. Often, the starting values of the variables that are passed
by reference are unimportant. Those values will be overwritten by the function, which may never even
look at any previous value.
It would be convenient if we could use the same convention in C#. However, C# requires that variables
be initialized with a starting value before they are referenced. Although we could initialize our input
variables with meaningless values before passing them into a function that will fill them with real,
meaningful ones, this practice seems at best needless and at worst confusing. However, there is a way
to short-circuit the C# compiler’s insistence on initial values for input arguments.
This is achieved with the out keyword. When a method’s input argument is prefixed with out, that
method can be passed a variable that has not been initialized. The variable is passed by reference, so any
changes that the method makes to the variable will persist when control returns from the called method.
Again, we also need to use the out keyword when we call the method, as well as when we define it:
static void SomeFunction(out int i)
{
i = 100;
}
public static int Main()
{
int i; // note how i is declared but not initialized
SomeFunction(out i);
Console.WriteLine(i);
return 0;
}
The out keyword is an example of something new in C# that has no analogy in either Visual Basic or
C++, and which has been introduced to make C# more secure against bugs. If an out parameter isn’t
assigned a value within the body of the function, the method won’t compile.
Method overloading
C# supports method overloading—several versions of the method that have different signatures (that is,
the name, number of parameters, and parameter types). However, C# does not support default parameters
in the way that, say, C++ or Visual Basic do. In order to overload methods, you simply declare the
methods with the same name but different numbers or types of parameters:
91
Objects and Types
class ResultDisplayer
{
void DisplayResult(string result)
{
// implementation
}
void DisplayResult(int result)
{
// implementation
}
}
Because C# does not support optional parameters, you will need to use method overloading to achieve
the same effect:
class MyClass
{
int DoSomething(int x) // want 2nd parameter with default value 10
{
DoSomething(x, 10);
}
int DoSomething(int x, int y)
{
// implementation
}
}
As in any language, method overloading carries with it the potential for subtle runtime bugs if the
wrong overload is called. In Chapter 4 we discuss how to code defensively against these problems. For
now, we’ll point out that C# does place some minimum differences on the parameters of overloaded
methods.
❑ It is not sufficient for two methods to differ only in their return type.
❑ It is not sufficient for two methods to differ only by virtue of a parameter having been declared
as ref or out.
From "Pro C# 3rd"
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.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; // 添加这些别名解决命名冲突 using SysException = System.Exception; using AcadException = Autodesk.AutoCAD.Runtime.Exception; using Point = System.Drawing.Point; using Size = System.Drawing.Size; using Label = System.Windows.Forms.Label; using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application; using WinFormsDialogResult = System.Windows.Forms.DialogResult; namespace BeamSectionPlugin { public class BeamParameters { public int Thickness { get; set; } = 15; // 梁下设置 public BeamBottomSetting BeamBottom { get; set; } = new BeamBottomSetting(); // 梁侧设置 public BeamSideSetting BeamSide { get; set; } = new BeamSideSetting(); // 板下设置 public SlabSetting Slab { get; set; } = new SlabSetting(); } public class BeamBottomSetting { public string SecondaryMaterial { get; set; } = "木方"; public string SecondarySpec { get; set; } = "40x90"; public string SecondaryDirection { get; set; } = "横向"; public string SecondarySpacing { get; set; } = "@200"; public string PrimaryMaterial { get; set; } = "木方"; public string PrimarySpec { get; set; } = "100x100"; public string PrimaryDirection { get; set; } = "纵向"; public string PrimarySpacing { get; set; } = ""; // 新增主龙骨间距 } public class BeamSideSetting { public bool Enabled { get; set; } = false; public string SecondaryMaterial { get; set; } = "木方"; public string SecondarySpec { get; set; } = "40x90"; public string SecondaryDirection { get; set; } = "垂直"; public string SecondarySpacing { get; set; } = "@200"; public string PrimaryMaterial { get; set; } = "木方"; public string PrimarySpec { get; set; } = "100x100"; public string PrimaryLayout { get; set; } = "双拼"; // 从PrimaryDirection改为PrimaryLayout public string PrimarySpacing { get; set; } = ""; // 对拉螺栓设置 public double BoltDiameter { get; set; } = 12; public double BoltStartHeight { get; set; } = 50; public double BoltSlabHeight { get; set; } = 250; public double BoltSpacing { get; set; } = 500; } public class SlabSetting { public string SecondaryMaterial { get; set; } = "木方"; public string SecondarySpec { get; set; } = "40x90"; public string SecondaryDirection { get; set; } = "横向"; public double SecondarySpacing { get; set; } = 200; public string PrimaryMaterial { get; set; } = "木方"; public string PrimarySpec { get; set; } = "100x100"; public string PrimaryDirection { get; set; } = "纵向"; public double PrimarySpacing { get; set; } = 0; // 新增主龙骨间距 } public class SlabParams { public double Thickness { get; set; } = 250; public double Offset { get; set; } = 0; } public class BeamSectionForm : Form { // 材料库数据 private readonly Dictionary<string, List<string>> materialLib = new Dictionary<string, List<string>> { {"木方", new List<string>{"40x90", "50x100", "100x100"}}, {"钢管", new List<string>{"Φ48x2.5", "Φ48x2.7", "Φ48x3"}}, {"方钢", new List<string>{"40x40x1.5", "50x50x1.5", "50x100x3"}}, {"工字钢", new List<string>{"I8", "I10", "I12", "I14", "I16"}} }; private TabControl mainTabControl; private Button btnDraw; private TextBox txtThickness; // 梁下设置控件 private ComboBox cmbBeamBottomSecMaterial; private ComboBox cmbBeamBottomSecSpec; private ComboBox cmbBeamBottomSecDirection; private TextBox txtBeamBottomSecSpacing; private ComboBox cmbBeamBottomPriMaterial; private ComboBox cmbBeamBottomPriSpec; private ComboBox cmbBeamBottomPriDirection; private TextBox txtBeamBottomPriSpacing; // 新增主龙骨间距输入框 // 梁侧设置控件 private CheckBox chkBeamSideEnabled; private ComboBox cmbBeamSideSecMaterial; private ComboBox cmbBeamSideSecSpec; private ComboBox cmbBeamSideSecDirection; private TextBox txtBeamSideSecSpacing; private ComboBox cmbBeamSidePriMaterial; private ComboBox cmbBeamSidePriSpec; private ComboBox cmbBeamSidePriLayout; // 从方向改为布置方式 private TextBox txtBeamSidePriSpacing; private TextBox txtBoltDiameter; private TextBox txtBoltStartHeight; private TextBox txtBoltSlabHeight; private TextBox txtBoltSpacing; // 板下设置控件 private ComboBox cmbSlabSecMaterial; private ComboBox cmbSlabSecSpec; private ComboBox cmbSlabSecDirection; private TextBox txtSlabSecSpacing; private ComboBox cmbSlabPriMaterial; private ComboBox cmbSlabPriSpec; private ComboBox cmbSlabPriDirection; private TextBox txtSlabPriSpacing; // 新增主龙骨间距输入框 public BeamSectionForm() { InitializeComponents(); } private void InitializeComponents() { try { this.Size = new Size(900, 800); // 增加窗体高度 this.Text = "梁板剖面图参数设置"; this.StartPosition = FormStartPosition.CenterScreen; this.Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F); // 主选项卡控件 mainTabControl = new TabControl { Location = new Point(10, 50), Size = new Size(870, 650), // 增加高度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; this.Controls.Add(mainTabControl); // 创建选项卡 CreateBeamBottomTab(); CreateSlabTab(); // 梁板统一模板厚 Label lblThickness = new Label { Text = "梁板统一模板厚(mm):", Location = new Point(20, 20), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; txtThickness = new TextBox { Location = new Point(170, 20), Width = 100, Text = "15", Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; this.Controls.Add(lblThickness); this.Controls.Add(txtThickness); // 开始绘制按钮 btnDraw = new Button { Text = "开始绘制", Location = new Point(400, 710), // 调整位置 Size = new Size(120, 40), Font = new System.Drawing.Font("Microsoft YaHei UI", 10, System.Drawing.FontStyle.Bold) }; btnDraw.Click += BtnDraw_Click; this.Controls.Add(btnDraw); } catch (SysException ex) { MessageBox.Show($"窗体初始化错误: {ex.Message}\n{ex.StackTrace}", "严重错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void CreateBeamBottomTab() { try { TabPage tabBeam = new TabPage("梁下及梁侧设置"); mainTabControl.TabPages.Add(tabBeam); // 梁下次龙骨设置分组 GroupBox gbBeamBottomSecondary = new GroupBox { Text = "梁下次龙骨设置", Location = new Point(10, 10), Size = new Size(850, 140), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabBeam.Controls.Add(gbBeamBottomSecondary); int yPos = 30; AddMaterialControls(gbBeamBottomSecondary, ref yPos, out cmbBeamBottomSecMaterial, out cmbBeamBottomSecSpec, out cmbBeamBottomSecDirection, out txtBeamBottomSecSpacing, true); // 设置默认值 if (cmbBeamBottomSecMaterial != null) cmbBeamBottomSecMaterial.SelectedIndex = 0; if (cmbBeamBottomSecSpec != null) cmbBeamBottomSecSpec.SelectedIndex = 0; if (cmbBeamBottomSecDirection != null) cmbBeamBottomSecDirection.SelectedIndex = 0; if (txtBeamBottomSecSpacing != null) txtBeamBottomSecSpacing.Text = "@200"; // 梁下主龙骨设置分组 - 新增间距输入框 GroupBox gbBeamBottomPrimary = new GroupBox { Text = "梁下主龙骨设置", Location = new Point(10, 160), Size = new Size(850, 140), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabBeam.Controls.Add(gbBeamBottomPrimary); yPos = 30; AddMaterialControls(gbBeamBottomPrimary, ref yPos, out cmbBeamBottomPriMaterial, out cmbBeamBottomPriSpec, out cmbBeamBottomPriDirection, out txtBeamBottomPriSpacing, true); // 设为true创建间距输入框 // 设置默认值 if (cmbBeamBottomPriMaterial != null) cmbBeamBottomPriMaterial.SelectedIndex = 0; if (cmbBeamBottomPriSpec != null) cmbBeamBottomPriSpec.SelectedIndex = 2; if (cmbBeamBottomPriDirection != null) cmbBeamBottomPriDirection.SelectedIndex = 1; if (txtBeamBottomPriSpacing != null) { txtBeamBottomPriSpacing.Text = ""; txtBeamBottomPriSpacing.Enabled = false; } // 梁侧设置分组 GroupBox gbBeamSide = new GroupBox { Text = "梁侧龙骨设置", Location = new Point(10, 310), Size = new Size(850, 200), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabBeam.Controls.Add(gbBeamSide); // 启用梁侧设置 chkBeamSideEnabled = new CheckBox { Text = "启用梁侧设置", Location = new Point(20, 25), Checked = false, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; chkBeamSideEnabled.CheckedChanged += ChkBeamSideEnabled_CheckedChanged; gbBeamSide.Controls.Add(chkBeamSideEnabled); // 梁侧次龙骨设置 yPos = 50; GroupBox gbBeamSideSecondary = new GroupBox { Text = "次龙骨", Location = new Point(20, 50), Size = new Size(810, 60), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSide.Controls.Add(gbBeamSideSecondary); int subYPos = 25; AddMaterialControls(gbBeamSideSecondary, ref subYPos, out cmbBeamSideSecMaterial, out cmbBeamSideSecSpec, out cmbBeamSideSecDirection, out txtBeamSideSecSpacing, true); // 设置默认值 if (cmbBeamSideSecMaterial != null) cmbBeamSideSecMaterial.SelectedIndex = 0; if (cmbBeamSideSecSpec != null) cmbBeamSideSecSpec.SelectedIndex = 0; if (cmbBeamSideSecDirection != null) cmbBeamSideSecDirection.SelectedIndex = 2; if (txtBeamSideSecSpacing != null) txtBeamSideSecSpacing.Text = "@200"; // 梁侧主龙骨设置 - 改为布置方式 yPos = 120; GroupBox gbBeamSidePrimary = new GroupBox { Text = "主龙骨", Location = new Point(20, 120), Size = new Size(810, 60), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSide.Controls.Add(gbBeamSidePrimary); subYPos = 25; // 材料选择 Label lblPriMaterial = new Label { Text = "材料:", Location = new Point(20, subYPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSidePrimary.Controls.Add(lblPriMaterial); cmbBeamSidePriMaterial = new ComboBox { Location = new Point(60, subYPos), Width = 100, DropDownStyle = ComboBoxStyle.DropDownList, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; cmbBeamSidePriMaterial.Items.AddRange(new object[] { "木方", "钢管", "方钢", "工字钢" }); cmbBeamSidePriMaterial.SelectedIndex = 0; cmbBeamSidePriMaterial.SelectedIndexChanged += Material_SelectedIndexChanged; gbBeamSidePrimary.Controls.Add(cmbBeamSidePriMaterial); // 规格选择 Label lblPriSpec = new Label { Text = "规格:", Location = new Point(170, subYPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSidePrimary.Controls.Add(lblPriSpec); cmbBeamSidePriSpec = new ComboBox { Location = new Point(210, subYPos), Width = 100, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; UpdateSpecOptions(cmbBeamSidePriMaterial, cmbBeamSidePriSpec); gbBeamSidePrimary.Controls.Add(cmbBeamSidePriSpec); // 布置方式 (从方向改为布置方式) Label lblPriLayout = new Label { Text = "布置方式:", Location = new Point(320, subYPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSidePrimary.Controls.Add(lblPriLayout); cmbBeamSidePriLayout = new ComboBox { Location = new Point(390, subYPos), Width = 80, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; cmbBeamSidePriLayout.Items.AddRange(new object[] { "双拼", "单根" }); cmbBeamSidePriLayout.SelectedIndex = 0; gbBeamSidePrimary.Controls.Add(cmbBeamSidePriLayout); // 间距设置 (梁侧主龙骨不需要间距) Label lblPriSpacing = new Label { Text = "间距:", Location = new Point(480, subYPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSidePrimary.Controls.Add(lblPriSpacing); txtBeamSidePriSpacing = new TextBox { Location = new Point(520, subYPos), Width = 80, Text = "", Enabled = false, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSidePrimary.Controls.Add(txtBeamSidePriSpacing); // 对拉螺栓设置分组 - 增加宽度确保显示完整 GroupBox gbBolts = new GroupBox { Text = "对拉螺栓设置", Location = new Point(10, 520), Size = new Size(850, 100), // 增加高度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabBeam.Controls.Add(gbBolts); // 螺栓参数 - 调整布局确保全部显示 int xPos = 20; int yBoltPos = 30; AddBoltControl(gbBolts, "螺栓直径(mm):", ref xPos, yBoltPos, out txtBoltDiameter, "12"); AddBoltControl(gbBolts, "底部距梁底高(mm):", ref xPos, yBoltPos, out txtBoltStartHeight, "50"); // 第二行 xPos = 20; yBoltPos = 60; AddBoltControl(gbBolts, "板底距螺栓高(mm):", ref xPos, yBoltPos, out txtBoltSlabHeight, "250"); AddBoltControl(gbBolts, "螺栓间距(mm):", ref xPos, yBoltPos, out txtBoltSpacing, "500"); } catch (SysException ex) { MessageBox.Show($"创建梁下选项卡错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); throw; } } private void CreateSlabTab() { try { TabPage tabSlab = new TabPage("板下设置"); mainTabControl.TabPages.Add(tabSlab); // 板下次龙骨设置分组 GroupBox gbSlabSecondary = new GroupBox { Text = "板下次龙骨设置", Location = new Point(10, 20), Size = new Size(850, 140), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabSlab.Controls.Add(gbSlabSecondary); int yPos = 30; AddMaterialControls(gbSlabSecondary, ref yPos, out cmbSlabSecMaterial, out cmbSlabSecSpec, out cmbSlabSecDirection, out txtSlabSecSpacing, true); // 设置默认值 if (cmbSlabSecMaterial != null) cmbSlabSecMaterial.SelectedIndex = 0; if (cmbSlabSecSpec != null) cmbSlabSecSpec.SelectedIndex = 0; if (cmbSlabSecDirection != null) cmbSlabSecDirection.SelectedIndex = 0; if (txtSlabSecSpacing != null) txtSlabSecSpacing.Text = "200"; // 板下主龙骨设置分组 - 新增间距输入框 GroupBox gbSlabPrimary = new GroupBox { Text = "板下主龙骨设置", Location = new Point(10, 170), Size = new Size(850, 140), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabSlab.Controls.Add(gbSlabPrimary); yPos = 30; AddMaterialControls(gbSlabPrimary, ref yPos, out cmbSlabPriMaterial, out cmbSlabPriSpec, out cmbSlabPriDirection, out txtSlabPriSpacing, true); // 设为true创建间距输入框 // 设置默认值 if (cmbSlabPriMaterial != null) cmbSlabPriMaterial.SelectedIndex = 0; if (cmbSlabPriSpec != null) cmbSlabPriSpec.SelectedIndex = 2; if (cmbSlabPriDirection != null) cmbSlabPriDirection.SelectedIndex = 1; if (txtSlabPriSpacing != null) { txtSlabPriSpacing.Text = ""; txtSlabPriSpacing.Enabled = false; } } catch (SysException ex) { MessageBox.Show($"创建板下选项卡错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); throw; } } private void AddMaterialControls(Control parent, ref int yPos, out ComboBox cmbMaterial, out ComboBox cmbSpec, out ComboBox cmbDirection, out TextBox txtSpacing, bool includeSpacing) { cmbMaterial = null; cmbSpec = null; cmbDirection = null; txtSpacing = null; try { // 材料选择 Label lblMaterial = new Label { Text = "材料:", Location = new Point(20, yPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(lblMaterial); cmbMaterial = new ComboBox { Location = new Point(80, yPos), Width = 100, DropDownStyle = ComboBoxStyle.DropDownList, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; cmbMaterial.Items.AddRange(new object[] { "木方", "钢管", "方钢", "工字钢" }); cmbMaterial.SelectedIndex = 0; cmbMaterial.SelectedIndexChanged += Material_SelectedIndexChanged; // 正确使用 += parent.Controls.Add(cmbMaterial); // 规格选择 Label lblSpec = new Label { Text = "规格:", Location = new Point(200, yPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(lblSpec); cmbSpec = new ComboBox { Location = new Point(250, yPos), Width = 150, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; UpdateSpecOptions(cmbMaterial, cmbSpec); parent.Controls.Add(cmbSpec); // 布置方向 Label lblDirection = new Label { Text = "布置方向:", Location = new Point(420, yPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(lblDirection); cmbDirection = new ComboBox { Location = new Point(500, yPos), Width = 100, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; cmbDirection.Items.AddRange(new object[] { "横向", "纵向", "垂直" }); cmbDirection.SelectedIndex = 0; parent.Controls.Add(cmbDirection); // 间距设置(如果包含间距输入框) if (includeSpacing) { Label lblSpacing = new Label { Text = "间距:", Location = new Point(620, yPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(lblSpacing); txtSpacing = new TextBox { Location = new Point(670, yPos), Width = 100, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F), Tag = parent.Text // 保存父分组名称用于识别 }; parent.Controls.Add(txtSpacing); // 使用局部变量解决 lambda 表达式中的问题 TextBox localTxtSpacing = txtSpacing; ComboBox localCmbDirection = cmbDirection; Label localLblSpacing = lblSpacing; // 正确使用 += 附加事件 cmbDirection.SelectedIndexChanged += (s, e) => { string direction = localCmbDirection.SelectedItem?.ToString(); string parentText = parent.Text; // 梁下主龙骨设置 if (parentText.Contains("梁下主龙骨")) { if (direction == "横向") { localTxtSpacing.Enabled = true; localTxtSpacing.BackColor = SystemColors.Window; localLblSpacing.Text = "长度(mm):"; } else { localTxtSpacing.Enabled = false; localTxtSpacing.BackColor = SystemColors.Control; localLblSpacing.Text = "间距:"; } } // 板下主龙骨设置 else if (parentText.Contains("板下主龙骨")) { if (direction == "横向") { localTxtSpacing.Enabled = true; localTxtSpacing.BackColor = SystemColors.Window; localLblSpacing.Text = "留空距离(mm):"; } else { localTxtSpacing.Enabled = false; localTxtSpacing.BackColor = SystemColors.Control; localLblSpacing.Text = "间距:"; } } }; // 初始化状态 cmbDirection.SelectedIndexChanged?.Invoke(cmbDirection, EventArgs.Empty); } yPos += 40; } catch (SysException ex) { MessageBox.Show($"添加材料控件错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); throw; } } private void AddBoltControl(Control parent, string label, ref int xPos, int yPos, out TextBox textBox, string defaultValue) { textBox = new TextBox(); try { Label lbl = new Label { Text = label, Location = new Point(xPos, yPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(lbl); textBox = new TextBox { Location = new Point(xPos + lbl.Width + 5, yPos), Width = 100, Text = defaultValue, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(textBox); xPos += lbl.Width + 110; } catch (SysException ex) { MessageBox.Show($"添加螺栓控件错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); throw; } } private void Material_SelectedIndexChanged(object sender, EventArgs e) { try { ComboBox cmbMaterial = sender as ComboBox; if (cmbMaterial == null) return; foreach (Control ctrl in cmbMaterial.Parent.Controls) { if (ctrl is ComboBox cmbSpec && ctrl != cmbMaterial && ctrl.Location.Y == cmbMaterial.Location.Y) { UpdateSpecOptions(cmbMaterial, cmbSpec); break; } } } catch (SysException ex) { MessageBox.Show($"材料选择变更错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void UpdateSpecOptions(ComboBox cmbMaterial, ComboBox cmbSpec) { try { if (cmbMaterial?.SelectedItem == null) return; var material = cmbMaterial.SelectedItem.ToString(); if (cmbSpec == null) return; cmbSpec.Items.Clear(); if (materialLib.ContainsKey(material)) { cmbSpec.Items.AddRange(materialLib[material].ToArray()); if (cmbSpec.Items.Count > 0) cmbSpec.SelectedIndex = 0; } } catch (SysException ex) { MessageBox.Show($"更新规格选项错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void ChkBeamSideEnabled_CheckedChanged(object sender, EventArgs e) { try { bool enabled = chkBeamSideEnabled.Checked; if (cmbBeamSideSecMaterial != null) cmbBeamSideSecMaterial.Enabled = enabled; if (cmbBeamSideSecSpec != null) cmbBeamSideSecSpec.Enabled = enabled; if (cmbBeamSideSecDirection != null) cmbBeamSideSecDirection.Enabled = enabled; if (txtBeamSideSecSpacing != null) txtBeamSideSecSpacing.Enabled = enabled; if (cmbBeamSidePriMaterial != null) cmbBeamSidePriMaterial.Enabled = enabled; if (cmbBeamSidePriSpec != null) cmbBeamSidePriSpec.Enabled = enabled; if (cmbBeamSidePriLayout != null) cmbBeamSidePriLayout.Enabled = enabled; if (txtBeamSidePriSpacing != null) txtBeamSidePriSpacing.Enabled = enabled; if (txtBoltDiameter != null) txtBoltDiameter.Enabled = enabled; if (txtBoltStartHeight != null) txtBoltStartHeight.Enabled = enabled; if (txtBoltSlabHeight != null) txtBoltSlabHeight.Enabled = enabled; if (txtBoltSpacing != null) txtBoltSpacing.Enabled = enabled; } catch (SysException ex) { MessageBox.Show($"梁侧启用状态变更错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void BtnDraw_Click(object sender, EventArgs e) { try { if (!ValidateInputs()) { MessageBox.Show("请填写所有必填参数", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } this.DialogResult = WinFormsDialogResult.OK; this.Close(); } catch (SysException ex) { MessageBox.Show($"按钮点击错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private bool ValidateInputs() { try { if (string.IsNullOrEmpty(txtThickness.Text) || !int.TryParse(txtThickness.Text, out _)) return false; // 梁下次龙骨 if (string.IsNullOrEmpty(txtBeamBottomSecSpacing.Text)) return false; // 梁下主龙骨 - 当方向为横向时需要长度 string beamBottomPriDirection = cmbBeamBottomPriDirection?.SelectedItem?.ToString(); if (beamBottomPriDirection == "横向" && (string.IsNullOrEmpty(txtBeamBottomPriSpacing.Text) || !double.TryParse(txtBeamBottomPriSpacing.Text, out _))) return false; // 梁侧设置 if (chkBeamSideEnabled.Checked) { if (string.IsNullOrEmpty(txtBeamSideSecSpacing.Text)) return false; // 对拉螺栓参数 if (!double.TryParse(txtBoltDiameter.Text, out _) || !double.TryParse(txtBoltStartHeight.Text, out _) || !double.TryParse(txtBoltSlabHeight.Text, out _) || !double.TryParse(txtBoltSpacing.Text, out _)) return false; } // 板下次龙骨 if (!double.TryParse(txtSlabSecSpacing.Text, out _)) return false; // 板下主龙骨 - 当方向为横向时需要留空距离 string slabPriDirection = cmbSlabPriDirection?.SelectedItem?.ToString(); if (slabPriDirection == "横向" && (string.IsNullOrEmpty(txtSlabPriSpacing.Text) || !double.TryParse(txtSlabPriSpacing.Text, out _))) return false; return true; } catch (SysException ex) { MessageBox.Show($"输入验证错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } public BeamParameters GetParameters() { try { var parameters = new BeamParameters { Thickness = int.TryParse(txtThickness.Text, out int thick) ? thick : 15, BeamBottom = new BeamBottomSetting { SecondaryMaterial = cmbBeamBottomSecMaterial?.SelectedItem?.ToString() ?? "木方", SecondarySpec = cmbBeamBottomSecSpec?.SelectedItem?.ToString() ?? "40x90", SecondaryDirection = cmbBeamBottomSecDirection?.SelectedItem?.ToString() ?? "横向", SecondarySpacing = txtBeamBottomSecSpacing?.Text ?? "@200", PrimaryMaterial = cmbBeamBottomPriMaterial?.SelectedItem?.ToString() ?? "木方", PrimarySpec = cmbBeamBottomPriSpec?.SelectedItem?.ToString() ?? "100x100", PrimaryDirection = cmbBeamBottomPriDirection?.SelectedItem?.ToString() ?? "纵向", PrimarySpacing = txtBeamBottomPriSpacing?.Text ?? "" }, BeamSide = new BeamSideSetting { Enabled = chkBeamSideEnabled.Checked, SecondaryMaterial = cmbBeamSideSecMaterial?.SelectedItem?.ToString() ?? "木方", SecondarySpec = cmbBeamSideSecSpec?.SelectedItem?.ToString() ?? "40x90", SecondaryDirection = cmbBeamSideSecDirection?.SelectedItem?.ToString() ?? "垂直", SecondarySpacing = txtBeamSideSecSpacing?.Text ?? "@200", PrimaryMaterial = cmbBeamSidePriMaterial?.SelectedItem?.ToString() ?? "木方", PrimarySpec = cmbBeamSidePriSpec?.SelectedItem?.ToString() ?? "100x100", PrimaryLayout = cmbBeamSidePriLayout?.SelectedItem?.ToString() ?? "双拼", PrimarySpacing = txtBeamSidePriSpacing?.Text ?? "", BoltDiameter = double.TryParse(txtBoltDiameter.Text, out double boltDia) ? boltDia : 12, BoltStartHeight = double.TryParse(txtBoltStartHeight.Text, out double boltStart) ? boltStart : 50, BoltSlabHeight = double.TryParse(txtBoltSlabHeight.Text, out double boltSlab) ? boltSlab : 250, BoltSpacing = double.TryParse(txtBoltSpacing.Text, out double boltSpace) ? boltSpace : 500 }, Slab = new SlabSetting { SecondaryMaterial = cmbSlabSecMaterial?.SelectedItem?.ToString() ?? "木方", SecondarySpec = cmbSlabSecSpec?.SelectedItem?.ToString() ?? "40x90", SecondaryDirection = cmbSlabSecDirection?.SelectedItem?.ToString() ?? "横向", SecondarySpacing = double.TryParse(txtSlabSecSpacing.Text, out double secSpacing) ? secSpacing : 200, PrimaryMaterial = cmbSlabPriMaterial?.SelectedItem?.ToString() ?? "木方", PrimarySpec = cmbSlabPriSpec?.SelectedItem?.ToString() ?? "100x100", PrimaryDirection = cmbSlabPriDirection?.SelectedItem?.ToString() ?? "纵向", PrimarySpacing = double.TryParse(txtSlabPriSpacing.Text, out double priSpacing) ? priSpacing : 0 } }; return parameters; } catch (SysException ex) { MessageBox.Show($"获取参数错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return new BeamParameters(); } } } public class BeamSectionCommands { [CommandMethod("DB")] public static void DrawBeamSection() { try { var doc = AcadApplication.DocumentManager.MdiActiveDocument; if (doc == null) { AcadApplication.ShowAlertDialog("没有活动文档!"); return; } var db = doc.Database; var ed = doc.Editor; ed.WriteMessage("\n梁板剖面图绘制命令启动..."); using (var form = new BeamSectionForm()) { ed.WriteMessage("\n显示参数设置窗体..."); var res = AcadApplication.ShowModalDialog(form); if (res != WinFormsDialogResult.OK) { ed.WriteMessage("\n用户取消操作。"); return; } // 获取参数 ed.WriteMessage("\n获取参数设置..."); var parameters = form.GetParameters(); // 获取梁的两个点 ed.WriteMessage("\n请指定梁的第一个点..."); Point3d startPt = GetPoint(ed, "绘制梁的第1个点:"); if (double.IsNaN(startPt.X)) { ed.WriteMessage("\n未指定第一点,操作取消。"); return; } ed.WriteMessage("\n请指定梁的第二个点..."); Point3d endPt = GetPoint(ed, "绘制梁的第2个点:", startPt); if (double.IsNaN(endPt.X)) { ed.WriteMessage("\n未指定第二点,操作取消。"); return; } // 获取梁高 ed.WriteMessage("\n请输入梁高..."); double beamHeight = GetHeight(ed); if (double.IsNaN(beamHeight)) { ed.WriteMessage("\n未输入梁高,操作取消。"); return; } // 获取板参数 ed.WriteMessage("\n请设置板参数..."); SlabParams slabParams = GetSlabParameters(ed); if (slabParams == null) { ed.WriteMessage("\n未设置板参数,操作取消。"); return; } // 开始事务 using (var tr = db.TransactionManager.StartTransaction()) { try { ed.WriteMessage("\n开始创建梁板剖面..."); CreateBeamSection(db, tr, startPt, endPt, beamHeight, slabParams, parameters); tr.Commit(); ed.WriteMessage("\n梁板剖面图绘制完成!"); } catch (SysException ex) { tr.Abort(); ed.WriteMessage($"\n绘图过程中出错: {ex.Message}\n{ex.StackTrace}"); if (ex.InnerException != null) { ed.WriteMessage($"\n内部错误: {ex.InnerException.Message}"); } } } } } catch (SysException ex) { var doc = AcadApplication.DocumentManager.MdiActiveDocument; if (doc != null) { var ed = doc.Editor; ed.WriteMessage($"\n严重错误: {ex.Message}\n{ex.StackTrace}"); } else { MessageBox.Show($"严重错误: {ex.Message}", "梁板剖面图错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } private static Point3d GetPoint(Editor ed, string message, Point3d? basePoint = null) { try { var opts = new PromptPointOptions(message); if (basePoint.HasValue) { opts.UseBasePoint = true; opts.BasePoint = basePoint.Value; } var res = ed.GetPoint(opts); return res.Status == PromptStatus.OK ? res.Value : new Point3d(double.NaN, double.NaN, double.NaN); } catch { return new Point3d(double.NaN, double.NaN, double.NaN); } } private static double GetHeight(Editor ed) { try { var opts = new PromptDoubleOptions("输入梁高(mm):"); opts.AllowNegative = false; var res = ed.GetDouble(opts); return res.Status == PromptStatus.OK ? res.Value : double.NaN; } catch { return double.NaN; } } private static SlabParams GetSlabParameters(Editor ed) { try { var pko = new PromptKeywordOptions("\n请选择板参数设置[板厚(A)/升降板(S)]:"); pko.Keywords.Add("A"); pko.Keywords.Add("S"); pko.Keywords.Default = "A"; var pkr = ed.GetKeywords(pko); if (pkr.Status != PromptStatus.OK) return null; double thickness = 250; double offset = 0; if (pkr.StringResult == "A" || pkr.StringResult == "S") { var pdo = new PromptDoubleOptions("\n输入板厚(mm):"); pdo.DefaultValue = 250; pdo.AllowNegative = false; var pdr = ed.GetDouble(pdo); if (pdr.Status != PromptStatus.OK) return null; thickness = pdr.Value; if (pkr.StringResult == "S") { pdo = new PromptDoubleOptions("\n输入升降高度(mm):"); pdo.AllowNegative = true; pdr = ed.GetDouble(pdo); if (pdr.Status != PromptStatus.OK) return null; offset = pdr.Value; } } return new SlabParams { Thickness = thickness, Offset = offset }; } catch { return null; } } private static void CreateBeamSection(Database db, Transaction tr, Point3d startPt, Point3d endPt, double beamHeight, SlabParams slabParams, BeamParameters parameters) { var btr = (BlockTableRecord)tr.GetObject( SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite); // 1. 创建梁板闭合多段线 var beamPolyline = CreateBeamPolyline(startPt, endPt, beamHeight, slabParams); if (beamPolyline == null) throw new SysException("创建梁板多段线失败"); btr.AppendEntity(beamPolyline); tr.AddNewlyCreatedDBObject(beamPolyline, true); // 2. 填充混凝土图案 var hatch = new Hatch(); btr.AppendEntity(hatch); tr.AddNewlyCreatedDBObject(hatch, true); hatch.SetHatchPattern(HatchPatternType.PreDefined, "AR-CONC"); hatch.Associative = true; hatch.AppendLoop(HatchLoopTypes.Outermost, new ObjectIdCollection { beamPolyline.ObjectId }); hatch.PatternScale = 50; // 3. 标注尺寸 CreateDimension(btr, tr, startPt, endPt, beamHeight, slabParams); // 4. 绘制主次龙骨 DrawBeamBottomMembers(btr, tr, beamPolyline, parameters); DrawSlabMembers(btr, tr, beamPolyline, parameters); } private static Polyline CreateBeamPolyline(Point3d start, Point3d end, double height, SlabParams slab) { Vector3d dir = (end - start).GetNormal(); Vector3d perp = new Vector3d(-dir.Y, dir.X, 0) * height; double slabThickness = slab.Thickness; double slabOffset = slab.Offset; var pline = new Polyline(); pline.AddVertexAt(0, new Point2d(start.X, start.Y), 0, 0, 0); pline.AddVertexAt(1, new Point2d(end.X, end.Y), 0, 0, 0); pline.AddVertexAt(2, new Point2d(end.X + perp.X, end.Y + perp.Y), 0, 0, 0); Point3d slabPoint = new Point3d( start.X + perp.X + dir.X * slabOffset, start.Y + perp.Y + dir.Y * slabOffset, 0); pline.AddVertexAt(3, new Point2d(slabPoint.X, slabPoint.Y), 0, 0, 0); Vector3d slabDir = dir * slabThickness; pline.AddVertexAt(4, new Point2d(slabPoint.X + slabDir.X, slabPoint.Y + slabDir.Y), 0, 0, 0); pline.AddVertexAt(5, new Point2d(end.X + slabDir.X, end.Y + slabDir.Y), 0, 0, 0); pline.AddVertexAt(6, new Point2d(start.X + slabDir.X, start.Y + slabDir.Y), 0, 0, 0); pline.Closed = true; return pline; } private static void DrawBeamBottomMembers(BlockTableRecord btr, Transaction tr, Polyline beamPoly, BeamParameters parameters) { double beamLength = beamPoly.Length; // 梁下次龙骨 if (parameters.BeamBottom.SecondaryDirection == "横向") { double spacing = ParseSpacing(parameters.BeamBottom.SecondarySpacing, beamLength); for (double pos = spacing; pos < beamLength; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.BeamBottom.SecondarySpec, 0); } } // 梁下主龙骨 if (parameters.BeamBottom.PrimaryDirection == "横向") { // 横向布置时,使用输入的间距值 if (double.TryParse(parameters.BeamBottom.PrimarySpacing, out double spacing)) { for (double pos = spacing; pos < beamLength; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.BeamBottom.PrimarySpec, 0); } } } else if (parameters.BeamBottom.PrimaryDirection == "纵向") { // 纵向布置时,使用默认间距 double spacing = 1000; // 默认纵向间距 for (double pos = spacing; pos < beamLength; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.BeamBottom.PrimarySpec, 0); } } // 梁侧龙骨(如果启用) if (parameters.BeamSide.Enabled) { // 实现梁侧龙骨绘制逻辑... } } private static void DrawSlabMembers(BlockTableRecord btr, Transaction tr, Polyline beamPoly, BeamParameters parameters) { // 板下次龙骨 if (parameters.Slab.SecondaryDirection == "横向") { double spacing = parameters.Slab.SecondarySpacing; for (double pos = spacing; pos < beamPoly.Length; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.Slab.SecondarySpec, 0); } } // 板下主龙骨 if (parameters.Slab.PrimaryDirection == "横向") { // 横向布置时,使用输入的留空距离值 double spacing = parameters.Slab.PrimarySpacing; for (double pos = spacing; pos < beamPoly.Length - spacing; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.Slab.PrimarySpec, 0); } } else if (parameters.Slab.PrimaryDirection == "纵向") { // 纵向布置时,使用默认间距 double spacing = 1000; // 默认纵向间距 for (double pos = spacing; pos < beamPoly.Length; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.Slab.PrimarySpec, 0); } } } private static void DrawMemberSection(BlockTableRecord btr, Transaction tr, Point3d loc, string spec, double angle) { double width = 10, height = 10; ParseMemberSpec(spec, ref width, ref height); var rect = new Polyline(); rect.AddVertexAt(0, new Point2d(loc.X - width / 2, loc.Y - height / 2), 0, 0, 0); rect.AddVertexAt(1, new Point2d(loc.X + width / 2, loc.Y - height / 2), 0, 0, 0); rect.AddVertexAt(2, new Point2d(loc.X + width / 2, loc.Y + height / 2), 0, 0, 0); rect.AddVertexAt(3, new Point2d(loc.X - width / 2, loc.Y + height / 2), 0, 0, 0); rect.Closed = true; if (angle != 0) { Matrix3d rotation = Matrix3d.Rotation(angle, Vector3d.ZAxis, loc); rect.TransformBy(rotation); } btr.AppendEntity(rect); tr.AddNewlyCreatedDBObject(rect, true); } private static void ParseMemberSpec(string spec, ref double width, ref double height) { if (spec.Contains("x") && !spec.Contains("Φ")) { string[] parts = spec.Split('x'); if (parts.Length >= 2) { string wStr = new string(parts[0].Where(c => char.IsDigit(c) || c == '.').ToArray()); string hStr = new string(parts[1].Where(c => char.IsDigit(c) || c == '.').ToArray()); double.TryParse(wStr, out width); double.TryParse(hStr, out height); } } else if (spec.Contains("Φ")) { string diamPart = spec.Split('x')[0].Replace("Φ", ""); string wStr = new string(diamPart.Where(c => char.IsDigit(c) || c == '.').ToArray()); double.TryParse(wStr, out width); height = width; } else if (spec.StartsWith("I")) { string num = new string(spec.Where(char.IsDigit).ToArray()); if (int.TryParse(num, out int size)) { width = size * 0.5; height = size; } } if (width <= 0) width = 10; if (height <= 0) height = 10; } private static double ParseSpacing(string input, double totalLength) { if (input.Contains("@")) { string numPart = new string(input.Replace("@", "").Where(c => char.IsDigit(c) || c == '.').ToArray()); if (double.TryParse(numPart, out double spacing)) return spacing; } else if (input.Contains("根")) { string numPart = new string(input.Where(char.IsDigit).ToArray()); if (int.TryParse(numPart, out int count) && count > 1) return totalLength / (count - 1); } return 200; } private static void CreateDimension(BlockTableRecord btr, Transaction tr, Point3d start, Point3d end, double height, SlabParams slab) { var dimWidth = new AlignedDimension(); dimWidth.SetDatabaseDefaults(); dimWidth.XLine1Point = start; dimWidth.XLine2Point = end; dimWidth.DimLinePoint = new Point3d((start.X + end.X) / 2, start.Y - 50, 0); btr.AppendEntity(dimWidth); tr.AddNewlyCreatedDBObject(dimWidth, true); var dimHeight = new AlignedDimension(); dimHeight.SetDatabaseDefaults(); dimHeight.XLine1Point = start; dimHeight.XLine2Point = new Point3d(start.X, start.Y + height, 0); dimHeight.DimLinePoint = new Point3d(start.X - 50, start.Y + height / 2, 0); btr.AppendEntity(dimHeight); tr.AddNewlyCreatedDBObject(dimHeight, true); var dimSlab = new AlignedDimension(); dimSlab.SetDatabaseDefaults(); dimSlab.XLine1Point = new Point3d(end.X, end.Y + height, 0); dimSlab.XLine2Point = new Point3d(end.X, end.Y + height + slab.Thickness, 0); dimSlab.DimLinePoint = new Point3d(end.X + 50, end.Y + height + slab.Thickness / 2, 0); btr.AppendEntity(dimSlab); tr.AddNewlyCreatedDBObject(dimSlab, true); } } } 问题还是没解决:CS0079事件ComboBox.SelectedIndexChanged”只能出现在+=或-=的左边625行
08-03
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.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; // 添加这些别名解决命名冲突 using SysException = System.Exception; using AcadException = Autodesk.AutoCAD.Runtime.Exception; using Point = System.Drawing.Point; using Size = System.Drawing.Size; using Label = System.Windows.Forms.Label; using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application; using WinFormsDialogResult = System.Windows.Forms.DialogResult; namespace BeamSectionPlugin { public class BeamParameters { public int Thickness { get; set; } = 15; // 梁下设置 public BeamBottomSetting BeamBottom { get; set; } = new BeamBottomSetting(); // 梁侧设置 public BeamSideSetting BeamSide { get; set; } = new BeamSideSetting(); // 板下设置 public SlabSetting Slab { get; set; } = new SlabSetting(); } public class BeamBottomSetting { public string SecondaryMaterial { get; set; } = "木方"; public string SecondarySpec { get; set; } = "40x90"; public string SecondaryDirection { get; set; } = "横向"; public string SecondarySpacing { get; set; } = "@200"; public string PrimaryMaterial { get; set; } = "木方"; public string PrimarySpec { get; set; } = "100x100"; public string PrimaryDirection { get; set; } = "纵向"; public string PrimarySpacing { get; set; } = ""; // 新增主龙骨间距 } public class BeamSideSetting { public bool Enabled { get; set; } = false; public string SecondaryMaterial { get; set; } = "木方"; public string SecondarySpec { get; set; } = "40x90"; public string SecondaryDirection { get; set; } = "垂直"; public string SecondarySpacing { get; set; } = "@200"; public string PrimaryMaterial { get; set; } = "木方"; public string PrimarySpec { get; set; } = "100x100"; public string PrimaryLayout { get; set; } = "双拼"; // 从PrimaryDirection改为PrimaryLayout public string PrimarySpacing { get; set; } = ""; // 对拉螺栓设置 public double BoltDiameter { get; set; } = 12; public double BoltStartHeight { get; set; } = 50; public double BoltSlabHeight { get; set; } = 250; public double BoltSpacing { get; set; } = 500; } public class SlabSetting { public string SecondaryMaterial { get; set; } = "木方"; public string SecondarySpec { get; set; } = "40x90"; public string SecondaryDirection { get; set; } = "横向"; public double SecondarySpacing { get; set; } = 200; public string PrimaryMaterial { get; set; } = "木方"; public string PrimarySpec { get; set; } = "100x100"; public string PrimaryDirection { get; set; } = "纵向"; public double PrimarySpacing { get; set; } = 0; // 新增主龙骨间距 } public class SlabParams { public double Thickness { get; set; } = 250; public double Offset { get; set; } = 0; } public class BeamSectionForm : Form { // 材料库数据 private readonly Dictionary<string, List<string>> materialLib = new Dictionary<string, List<string>> { {"木方", new List<string>{"40x90", "50x100", "100x100"}}, {"钢管", new List<string>{"Φ48x2.5", "Φ48x2.7", "Φ48x3"}}, {"方钢", new List<string>{"40x40x1.5", "50x50x1.5", "50x100x3"}}, {"工字钢", new List<string>{"I8", "I10", "I12", "I14", "I16"}} }; private TabControl mainTabControl; private Button btnDraw; private TextBox txtThickness; // 梁下设置控件 private ComboBox cmbBeamBottomSecMaterial; private ComboBox cmbBeamBottomSecSpec; private ComboBox cmbBeamBottomSecDirection; private TextBox txtBeamBottomSecSpacing; private ComboBox cmbBeamBottomPriMaterial; private ComboBox cmbBeamBottomPriSpec; private ComboBox cmbBeamBottomPriDirection; private TextBox txtBeamBottomPriSpacing; // 新增主龙骨间距输入框 // 梁侧设置控件 private CheckBox chkBeamSideEnabled; private ComboBox cmbBeamSideSecMaterial; private ComboBox cmbBeamSideSecSpec; private ComboBox cmbBeamSideSecDirection; private TextBox txtBeamSideSecSpacing; private ComboBox cmbBeamSidePriMaterial; private ComboBox cmbBeamSidePriSpec; private ComboBox cmbBeamSidePriLayout; // 从方向改为布置方式 private TextBox txtBeamSidePriSpacing; private TextBox txtBoltDiameter; private TextBox txtBoltStartHeight; private TextBox txtBoltSlabHeight; private TextBox txtBoltSpacing; // 板下设置控件 private ComboBox cmbSlabSecMaterial; private ComboBox cmbSlabSecSpec; private ComboBox cmbSlabSecDirection; private TextBox txtSlabSecSpacing; private ComboBox cmbSlabPriMaterial; private ComboBox cmbSlabPriSpec; private ComboBox cmbSlabPriDirection; private TextBox txtSlabPriSpacing; // 新增主龙骨间距输入框 public BeamSectionForm() { InitializeComponents(); } private void InitializeComponents() { try { this.Size = new Size(900, 800); // 增加窗体高度 this.Text = "梁板剖面图参数设置"; this.StartPosition = FormStartPosition.CenterScreen; this.Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F); // 主选项卡控件 mainTabControl = new TabControl { Location = new Point(10, 50), Size = new Size(870, 650), // 增加高度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; this.Controls.Add(mainTabControl); // 创建选项卡 CreateBeamBottomTab(); CreateSlabTab(); // 梁板统一模板厚 Label lblThickness = new Label { Text = "梁板统一模板厚(mm):", Location = new Point(20, 20), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; txtThickness = new TextBox { Location = new Point(170, 20), Width = 100, Text = "15", Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; this.Controls.Add(lblThickness); this.Controls.Add(txtThickness); // 开始绘制按钮 btnDraw = new Button { Text = "开始绘制", Location = new Point(400, 710), // 调整位置 Size = new Size(120, 40), Font = new System.Drawing.Font("Microsoft YaHei UI", 10, System.Drawing.FontStyle.Bold) }; btnDraw.Click += BtnDraw_Click; this.Controls.Add(btnDraw); } catch (SysException ex) { MessageBox.Show($"窗体初始化错误: {ex.Message}\n{ex.StackTrace}", "严重错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void CreateBeamBottomTab() { try { TabPage tabBeam = new TabPage("梁下及梁侧设置"); mainTabControl.TabPages.Add(tabBeam); // 梁下次龙骨设置分组 GroupBox gbBeamBottomSecondary = new GroupBox { Text = "梁下次龙骨设置", Location = new Point(10, 10), Size = new Size(850, 140), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabBeam.Controls.Add(gbBeamBottomSecondary); int yPos = 30; AddMaterialControls(gbBeamBottomSecondary, ref yPos, out cmbBeamBottomSecMaterial, out cmbBeamBottomSecSpec, out cmbBeamBottomSecDirection, out txtBeamBottomSecSpacing, true); // 设置默认值 if (cmbBeamBottomSecMaterial != null) cmbBeamBottomSecMaterial.SelectedIndex = 0; if (cmbBeamBottomSecSpec != null) cmbBeamBottomSecSpec.SelectedIndex = 0; if (cmbBeamBottomSecDirection != null) cmbBeamBottomSecDirection.SelectedIndex = 0; if (txtBeamBottomSecSpacing != null) txtBeamBottomSecSpacing.Text = "@200"; // 梁下主龙骨设置分组 - 新增间距输入框 GroupBox gbBeamBottomPrimary = new GroupBox { Text = "梁下主龙骨设置", Location = new Point(10, 160), Size = new Size(850, 140), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabBeam.Controls.Add(gbBeamBottomPrimary); yPos = 30; AddMaterialControls(gbBeamBottomPrimary, ref yPos, out cmbBeamBottomPriMaterial, out cmbBeamBottomPriSpec, out cmbBeamBottomPriDirection, out txtBeamBottomPriSpacing, true); // 设为true创建间距输入框 // 设置默认值 if (cmbBeamBottomPriMaterial != null) cmbBeamBottomPriMaterial.SelectedIndex = 0; if (cmbBeamBottomPriSpec != null) cmbBeamBottomPriSpec.SelectedIndex = 2; if (cmbBeamBottomPriDirection != null) cmbBeamBottomPriDirection.SelectedIndex = 1; if (txtBeamBottomPriSpacing != null) { txtBeamBottomPriSpacing.Text = ""; txtBeamBottomPriSpacing.Enabled = false; } // 梁侧设置分组 GroupBox gbBeamSide = new GroupBox { Text = "梁侧龙骨设置", Location = new Point(10, 310), Size = new Size(850, 200), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabBeam.Controls.Add(gbBeamSide); // 启用梁侧设置 chkBeamSideEnabled = new CheckBox { Text = "启用梁侧设置", Location = new Point(20, 25), Checked = false, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; chkBeamSideEnabled.CheckedChanged += ChkBeamSideEnabled_CheckedChanged; gbBeamSide.Controls.Add(chkBeamSideEnabled); // 梁侧次龙骨设置 yPos = 50; GroupBox gbBeamSideSecondary = new GroupBox { Text = "次龙骨", Location = new Point(20, 50), Size = new Size(810, 60), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSide.Controls.Add(gbBeamSideSecondary); int subYPos = 25; AddMaterialControls(gbBeamSideSecondary, ref subYPos, out cmbBeamSideSecMaterial, out cmbBeamSideSecSpec, out cmbBeamSideSecDirection, out txtBeamSideSecSpacing, true); // 设置默认值 if (cmbBeamSideSecMaterial != null) cmbBeamSideSecMaterial.SelectedIndex = 0; if (cmbBeamSideSecSpec != null) cmbBeamSideSecSpec.SelectedIndex = 0; if (cmbBeamSideSecDirection != null) cmbBeamSideSecDirection.SelectedIndex = 2; if (txtBeamSideSecSpacing != null) txtBeamSideSecSpacing.Text = "@200"; // 梁侧主龙骨设置 - 改为布置方式 yPos = 120; GroupBox gbBeamSidePrimary = new GroupBox { Text = "主龙骨", Location = new Point(20, 120), Size = new Size(810, 60), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSide.Controls.Add(gbBeamSidePrimary); subYPos = 25; // 材料选择 Label lblPriMaterial = new Label { Text = "材料:", Location = new Point(20, subYPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSidePrimary.Controls.Add(lblPriMaterial); cmbBeamSidePriMaterial = new ComboBox { Location = new Point(60, subYPos), Width = 100, DropDownStyle = ComboBoxStyle.DropDownList, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; cmbBeamSidePriMaterial.Items.AddRange(new object[] { "木方", "钢管", "方钢", "工字钢" }); cmbBeamSidePriMaterial.SelectedIndex = 0; cmbBeamSidePriMaterial.SelectedIndexChanged += Material_SelectedIndexChanged; gbBeamSidePrimary.Controls.Add(cmbBeamSidePriMaterial); // 规格选择 Label lblPriSpec = new Label { Text = "规格:", Location = new Point(170, subYPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSidePrimary.Controls.Add(lblPriSpec); cmbBeamSidePriSpec = new ComboBox { Location = new Point(210, subYPos), Width = 100, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; UpdateSpecOptions(cmbBeamSidePriMaterial, cmbBeamSidePriSpec); gbBeamSidePrimary.Controls.Add(cmbBeamSidePriSpec); // 布置方式 (从方向改为布置方式) Label lblPriLayout = new Label { Text = "布置方式:", Location = new Point(320, subYPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSidePrimary.Controls.Add(lblPriLayout); cmbBeamSidePriLayout = new ComboBox { Location = new Point(390, subYPos), Width = 80, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; cmbBeamSidePriLayout.Items.AddRange(new object[] { "双拼", "单根" }); cmbBeamSidePriLayout.SelectedIndex = 0; gbBeamSidePrimary.Controls.Add(cmbBeamSidePriLayout); // 间距设置 (梁侧主龙骨不需要间距) Label lblPriSpacing = new Label { Text = "间距:", Location = new Point(480, subYPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSidePrimary.Controls.Add(lblPriSpacing); txtBeamSidePriSpacing = new TextBox { Location = new Point(520, subYPos), Width = 80, Text = "", Enabled = false, Font = new System.Drawing.Font("Microsoft YaHei UI", 9F) }; gbBeamSidePrimary.Controls.Add(txtBeamSidePriSpacing); // 对拉螺栓设置分组 - 增加宽度确保显示完整 GroupBox gbBolts = new GroupBox { Text = "对拉螺栓设置", Location = new Point(10, 520), Size = new Size(850, 100), // 增加高度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabBeam.Controls.Add(gbBolts); // 螺栓参数 - 调整布局确保全部显示 int xPos = 20; int yBoltPos = 30; AddBoltControl(gbBolts, "螺栓直径(mm):", ref xPos, yBoltPos, out txtBoltDiameter, "12"); AddBoltControl(gbBolts, "底部距梁底高(mm):", ref xPos, yBoltPos, out txtBoltStartHeight, "50"); // 第二行 xPos = 20; yBoltPos = 60; AddBoltControl(gbBolts, "板底距螺栓高(mm):", ref xPos, yBoltPos, out txtBoltSlabHeight, "250"); AddBoltControl(gbBolts, "螺栓间距(mm):", ref xPos, yBoltPos, out txtBoltSpacing, "500"); } catch (SysException ex) { MessageBox.Show($"创建梁下选项卡错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); throw; } } private void CreateSlabTab() { try { TabPage tabSlab = new TabPage("板下设置"); mainTabControl.TabPages.Add(tabSlab); // 板下次龙骨设置分组 GroupBox gbSlabSecondary = new GroupBox { Text = "板下次龙骨设置", Location = new Point(10, 20), Size = new Size(850, 140), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabSlab.Controls.Add(gbSlabSecondary); int yPos = 30; AddMaterialControls(gbSlabSecondary, ref yPos, out cmbSlabSecMaterial, out cmbSlabSecSpec, out cmbSlabSecDirection, out txtSlabSecSpacing, true); // 设置默认值 if (cmbSlabSecMaterial != null) cmbSlabSecMaterial.SelectedIndex = 0; if (cmbSlabSecSpec != null) cmbSlabSecSpec.SelectedIndex = 0; if (cmbSlabSecDirection != null) cmbSlabSecDirection.SelectedIndex = 0; if (txtSlabSecSpacing != null) txtSlabSecSpacing.Text = "200"; // 板下主龙骨设置分组 - 新增间距输入框 GroupBox gbSlabPrimary = new GroupBox { Text = "板下主龙骨设置", Location = new Point(10, 170), Size = new Size(850, 140), // 增加宽度 Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; tabSlab.Controls.Add(gbSlabPrimary); yPos = 30; AddMaterialControls(gbSlabPrimary, ref yPos, out cmbSlabPriMaterial, out cmbSlabPriSpec, out cmbSlabPriDirection, out txtSlabPriSpacing, true); // 设为true创建间距输入框 // 设置默认值 if (cmbSlabPriMaterial != null) cmbSlabPriMaterial.SelectedIndex = 0; if (cmbSlabPriSpec != null) cmbSlabPriSpec.SelectedIndex = 2; if (cmbSlabPriDirection != null) cmbSlabPriDirection.SelectedIndex = 1; if (txtSlabPriSpacing != null) { txtSlabPriSpacing.Text = ""; txtSlabPriSpacing.Enabled = false; } } catch (SysException ex) { MessageBox.Show($"创建板下选项卡错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); throw; } } private void AddMaterialControls(Control parent, ref int yPos, out ComboBox cmbMaterial, out ComboBox cmbSpec, out ComboBox cmbDirection, out TextBox txtSpacing, bool includeSpacing) { cmbMaterial = new ComboBox(); cmbSpec = new ComboBox(); cmbDirection = new ComboBox(); txtSpacing = includeSpacing ? new TextBox() : null; try { // 材料选择 Label lblMaterial = new Label { Text = "材料:", Location = new Point(20, yPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(lblMaterial); cmbMaterial = new ComboBox { Location = new Point(80, yPos), Width = 100, DropDownStyle = ComboBoxStyle.DropDownList, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; cmbMaterial.Items.AddRange(new object[] { "木方", "钢管", "方钢", "工字钢" }); cmbMaterial.SelectedIndex = 0; cmbMaterial.SelectedIndexChanged += Material_SelectedIndexChanged; parent.Controls.Add(cmbMaterial); // 规格选择 Label lblSpec = new Label { Text = "规格:", Location = new Point(200, yPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(lblSpec); cmbSpec = new ComboBox { Location = new Point(250, yPos), Width = 150, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; UpdateSpecOptions(cmbMaterial, cmbSpec); parent.Controls.Add(cmbSpec); // 布置方向 Label lblDirection = new Label { Text = "布置方向:", Location = new Point(420, yPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(lblDirection); cmbDirection = new ComboBox { Location = new Point(500, yPos), Width = 100, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; cmbDirection.Items.AddRange(new object[] { "横向", "纵向", "垂直" }); cmbDirection.SelectedIndex = 0; parent.Controls.Add(cmbDirection); // 间距设置(如果包含间距输入框) if (includeSpacing) { Label lblSpacing = new Label { Text = "间距:", Location = new Point(620, yPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(lblSpacing); txtSpacing = new TextBox { Location = new Point(670, yPos), Width = 100, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F), Tag = parent.Text // 保存父分组名称用于识别 }; parent.Controls.Add(txtSpacing); // 使用局部变量解决 lambda 表达式中的问题 TextBox localTxtSpacing = txtSpacing; ComboBox localCmbDirection = cmbDirection; Label localLblSpacing = lblSpacing; // 添加方向变更事件处理 cmbDirection.SelectedIndexChanged += (s, e) => { string direction = localCmbDirection.SelectedItem?.ToString(); string parentText = parent.Text; // 梁下主龙骨设置 if (parentText.Contains("梁下主龙骨")) { if (direction == "横向") { localTxtSpacing.Enabled = true; localTxtSpacing.BackColor = SystemColors.Window; localLblSpacing.Text = "长度(mm):"; } else { localTxtSpacing.Enabled = false; localTxtSpacing.BackColor = SystemColors.Control; localLblSpacing.Text = "间距:"; } } // 板下主龙骨设置 else if (parentText.Contains("板下主龙骨")) { if (direction == "横向") { localTxtSpacing.Enabled = true; localTxtSpacing.BackColor = SystemColors.Window; localLblSpacing.Text = "留空距离(mm):"; } else { localTxtSpacing.Enabled = false; localTxtSpacing.BackColor = SystemColors.Control; localLblSpacing.Text = "间距:"; } } }; // 初始化状态 cmbDirection.SelectedIndexChanged?.Invoke(cmbDirection, EventArgs.Empty); } yPos += 40; } catch (SysException ex) { MessageBox.Show($"添加材料控件错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); throw; } } private void AddBoltControl(Control parent, string label, ref int xPos, int yPos, out TextBox textBox, string defaultValue) { textBox = new TextBox(); try { Label lbl = new Label { Text = label, Location = new Point(xPos, yPos), AutoSize = true, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(lbl); textBox = new TextBox { Location = new Point(xPos + lbl.Width + 5, yPos), Width = 100, Text = defaultValue, Font = new System.Drawing.Font("Microsoft YaHei UI", 9.75F) }; parent.Controls.Add(textBox); xPos += lbl.Width + 110; } catch (SysException ex) { MessageBox.Show($"添加螺栓控件错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); throw; } } private void Material_SelectedIndexChanged(object sender, EventArgs e) { try { ComboBox cmbMaterial = sender as ComboBox; if (cmbMaterial == null) return; foreach (Control ctrl in cmbMaterial.Parent.Controls) { if (ctrl is ComboBox cmbSpec && ctrl != cmbMaterial && ctrl.Location.Y == cmbMaterial.Location.Y) { UpdateSpecOptions(cmbMaterial, cmbSpec); break; } } } catch (SysException ex) { MessageBox.Show($"材料选择变更错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void UpdateSpecOptions(ComboBox cmbMaterial, ComboBox cmbSpec) { try { if (cmbMaterial?.SelectedItem == null) return; var material = cmbMaterial.SelectedItem.ToString(); if (cmbSpec == null) return; cmbSpec.Items.Clear(); if (materialLib.ContainsKey(material)) { cmbSpec.Items.AddRange(materialLib[material].ToArray()); if (cmbSpec.Items.Count > 0) cmbSpec.SelectedIndex = 0; } } catch (SysException ex) { MessageBox.Show($"更新规格选项错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void ChkBeamSideEnabled_CheckedChanged(object sender, EventArgs e) { try { bool enabled = chkBeamSideEnabled.Checked; if (cmbBeamSideSecMaterial != null) cmbBeamSideSecMaterial.Enabled = enabled; if (cmbBeamSideSecSpec != null) cmbBeamSideSecSpec.Enabled = enabled; if (cmbBeamSideSecDirection != null) cmbBeamSideSecDirection.Enabled = enabled; if (txtBeamSideSecSpacing != null) txtBeamSideSecSpacing.Enabled = enabled; if (cmbBeamSidePriMaterial != null) cmbBeamSidePriMaterial.Enabled = enabled; if (cmbBeamSidePriSpec != null) cmbBeamSidePriSpec.Enabled = enabled; if (cmbBeamSidePriLayout != null) cmbBeamSidePriLayout.Enabled = enabled; if (txtBeamSidePriSpacing != null) txtBeamSidePriSpacing.Enabled = enabled; if (txtBoltDiameter != null) txtBoltDiameter.Enabled = enabled; if (txtBoltStartHeight != null) txtBoltStartHeight.Enabled = enabled; if (txtBoltSlabHeight != null) txtBoltSlabHeight.Enabled = enabled; if (txtBoltSpacing != null) txtBoltSpacing.Enabled = enabled; } catch (SysException ex) { MessageBox.Show($"梁侧启用状态变更错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void BtnDraw_Click(object sender, EventArgs e) { try { if (!ValidateInputs()) { MessageBox.Show("请填写所有必填参数", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } this.DialogResult = WinFormsDialogResult.OK; this.Close(); } catch (SysException ex) { MessageBox.Show($"按钮点击错误: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private bool ValidateInputs() { try { if (string.IsNullOrEmpty(txtThickness.Text) || !int.TryParse(txtThickness.Text, out _)) return false; // 梁下次龙骨 if (string.IsNullOrEmpty(txtBeamBottomSecSpacing.Text)) return false; // 梁下主龙骨 - 当方向为横向时需要长度 string beamBottomPriDirection = cmbBeamBottomPriDirection?.SelectedItem?.ToString(); if (beamBottomPriDirection == "横向" && (string.IsNullOrEmpty(txtBeamBottomPriSpacing.Text) || !double.TryParse(txtBeamBottomPriSpacing.Text, out _))) return false; // 梁侧设置 if (chkBeamSideEnabled.Checked) { if (string.IsNullOrEmpty(txtBeamSideSecSpacing.Text)) return false; // 对拉螺栓参数 if (!double.TryParse(txtBoltDiameter.Text, out _) || !double.TryParse(txtBoltStartHeight.Text, out _) || !double.TryParse(txtBoltSlabHeight.Text, out _) || !double.TryParse(txtBoltSpacing.Text, out _)) return false; } // 板下次龙骨 if (!double.TryParse(txtSlabSecSpacing.Text, out _)) return false; // 板下主龙骨 - 当方向为横向时需要留空距离 string slabPriDirection = cmbSlabPriDirection?.SelectedItem?.ToString(); if (slabPriDirection == "横向" && (string.IsNullOrEmpty(txtSlabPriSpacing.Text) || !double.TryParse(txtSlabPriSpacing.Text, out _))) return false; return true; } catch (SysException ex) { MessageBox.Show($"输入验证错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } public BeamParameters GetParameters() { try { var parameters = new BeamParameters { Thickness = int.TryParse(txtThickness.Text, out int thick) ? thick : 15, BeamBottom = new BeamBottomSetting { SecondaryMaterial = cmbBeamBottomSecMaterial?.SelectedItem?.ToString() ?? "木方", SecondarySpec = cmbBeamBottomSecSpec?.SelectedItem?.ToString() ?? "40x90", SecondaryDirection = cmbBeamBottomSecDirection?.SelectedItem?.ToString() ?? "横向", SecondarySpacing = txtBeamBottomSecSpacing?.Text ?? "@200", PrimaryMaterial = cmbBeamBottomPriMaterial?.SelectedItem?.ToString() ?? "木方", PrimarySpec = cmbBeamBottomPriSpec?.SelectedItem?.ToString() ?? "100x100", PrimaryDirection = cmbBeamBottomPriDirection?.SelectedItem?.ToString() ?? "纵向", PrimarySpacing = txtBeamBottomPriSpacing?.Text ?? "" }, BeamSide = new BeamSideSetting { Enabled = chkBeamSideEnabled.Checked, SecondaryMaterial = cmbBeamSideSecMaterial?.SelectedItem?.ToString() ?? "木方", SecondarySpec = cmbBeamSideSecSpec?.SelectedItem?.ToString() ?? "40x90", SecondaryDirection = cmbBeamSideSecDirection?.SelectedItem?.ToString() ?? "垂直", SecondarySpacing = txtBeamSideSecSpacing?.Text ?? "@200", PrimaryMaterial = cmbBeamSidePriMaterial?.SelectedItem?.ToString() ?? "木方", PrimarySpec = cmbBeamSidePriSpec?.SelectedItem?.ToString() ?? "100x100", PrimaryLayout = cmbBeamSidePriLayout?.SelectedItem?.ToString() ?? "双拼", PrimarySpacing = txtBeamSidePriSpacing?.Text ?? "", BoltDiameter = double.TryParse(txtBoltDiameter.Text, out double boltDia) ? boltDia : 12, BoltStartHeight = double.TryParse(txtBoltStartHeight.Text, out double boltStart) ? boltStart : 50, BoltSlabHeight = double.TryParse(txtBoltSlabHeight.Text, out double boltSlab) ? boltSlab : 250, BoltSpacing = double.TryParse(txtBoltSpacing.Text, out double boltSpace) ? boltSpace : 500 }, Slab = new SlabSetting { SecondaryMaterial = cmbSlabSecMaterial?.SelectedItem?.ToString() ?? "木方", SecondarySpec = cmbSlabSecSpec?.SelectedItem?.ToString() ?? "40x90", SecondaryDirection = cmbSlabSecDirection?.SelectedItem?.ToString() ?? "横向", SecondarySpacing = double.TryParse(txtSlabSecSpacing.Text, out double secSpacing) ? secSpacing : 200, PrimaryMaterial = cmbSlabPriMaterial?.SelectedItem?.ToString() ?? "木方", PrimarySpec = cmbSlabPriSpec?.SelectedItem?.ToString() ?? "100x100", PrimaryDirection = cmbSlabPriDirection?.SelectedItem?.ToString() ?? "纵向", PrimarySpacing = double.TryParse(txtSlabPriSpacing.Text, out double priSpacing) ? priSpacing : 0 } }; return parameters; } catch (SysException ex) { MessageBox.Show($"获取参数错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return new BeamParameters(); } } } public class BeamSectionCommands { [CommandMethod("DB")] public static void DrawBeamSection() { try { var doc = AcadApplication.DocumentManager.MdiActiveDocument; if (doc == null) { AcadApplication.ShowAlertDialog("没有活动文档!"); return; } var db = doc.Database; var ed = doc.Editor; ed.WriteMessage("\n梁板剖面图绘制命令启动..."); using (var form = new BeamSectionForm()) { ed.WriteMessage("\n显示参数设置窗体..."); var res = AcadApplication.ShowModalDialog(form); if (res != WinFormsDialogResult.OK) { ed.WriteMessage("\n用户取消操作。"); return; } // 获取参数 ed.WriteMessage("\n获取参数设置..."); var parameters = form.GetParameters(); // 获取梁的两个点 ed.WriteMessage("\n请指定梁的第一个点..."); Point3d startPt = GetPoint(ed, "绘制梁的第1个点:"); if (double.IsNaN(startPt.X)) { ed.WriteMessage("\n未指定第一点,操作取消。"); return; } ed.WriteMessage("\n请指定梁的第二个点..."); Point3d endPt = GetPoint(ed, "绘制梁的第2个点:", startPt); if (double.IsNaN(endPt.X)) { ed.WriteMessage("\n未指定第二点,操作取消。"); return; } // 获取梁高 ed.WriteMessage("\n请输入梁高..."); double beamHeight = GetHeight(ed); if (double.IsNaN(beamHeight)) { ed.WriteMessage("\n未输入梁高,操作取消。"); return; } // 获取板参数 ed.WriteMessage("\n请设置板参数..."); SlabParams slabParams = GetSlabParameters(ed); if (slabParams == null) { ed.WriteMessage("\n未设置板参数,操作取消。"); return; } // 开始事务 using (var tr = db.TransactionManager.StartTransaction()) { try { ed.WriteMessage("\n开始创建梁板剖面..."); CreateBeamSection(db, tr, startPt, endPt, beamHeight, slabParams, parameters); tr.Commit(); ed.WriteMessage("\n梁板剖面图绘制完成!"); } catch (SysException ex) { tr.Abort(); ed.WriteMessage($"\n绘图过程中出错: {ex.Message}\n{ex.StackTrace}"); if (ex.InnerException != null) { ed.WriteMessage($"\n内部错误: {ex.InnerException.Message}"); } } } } } catch (SysException ex) { var doc = AcadApplication.DocumentManager.MdiActiveDocument; if (doc != null) { var ed = doc.Editor; ed.WriteMessage($"\n严重错误: {ex.Message}\n{ex.StackTrace}"); } else { MessageBox.Show($"严重错误: {ex.Message}", "梁板剖面图错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } private static Point3d GetPoint(Editor ed, string message, Point3d? basePoint = null) { try { var opts = new PromptPointOptions(message); if (basePoint.HasValue) { opts.UseBasePoint = true; opts.BasePoint = basePoint.Value; } var res = ed.GetPoint(opts); return res.Status == PromptStatus.OK ? res.Value : new Point3d(double.NaN, double.NaN, double.NaN); } catch { return new Point3d(double.NaN, double.NaN, double.NaN); } } private static double GetHeight(Editor ed) { try { var opts = new PromptDoubleOptions("输入梁高(mm):"); opts.AllowNegative = false; var res = ed.GetDouble(opts); return res.Status == PromptStatus.OK ? res.Value : double.NaN; } catch { return double.NaN; } } private static SlabParams GetSlabParameters(Editor ed) { try { var pko = new PromptKeywordOptions("\n请选择板参数设置[板厚(A)/升降板(S)]:"); pko.Keywords.Add("A"); pko.Keywords.Add("S"); pko.Keywords.Default = "A"; var pkr = ed.GetKeywords(pko); if (pkr.Status != PromptStatus.OK) return null; double thickness = 250; double offset = 0; if (pkr.StringResult == "A" || pkr.StringResult == "S") { var pdo = new PromptDoubleOptions("\n输入板厚(mm):"); pdo.DefaultValue = 250; pdo.AllowNegative = false; var pdr = ed.GetDouble(pdo); if (pdr.Status != PromptStatus.OK) return null; thickness = pdr.Value; if (pkr.StringResult == "S") { pdo = new PromptDoubleOptions("\n输入升降高度(mm):"); pdo.AllowNegative = true; pdr = ed.GetDouble(pdo); if (pdr.Status != PromptStatus.OK) return null; offset = pdr.Value; } } return new SlabParams { Thickness = thickness, Offset = offset }; } catch { return null; } } private static void CreateBeamSection(Database db, Transaction tr, Point3d startPt, Point3d endPt, double beamHeight, SlabParams slabParams, BeamParameters parameters) { var btr = (BlockTableRecord)tr.GetObject( SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite); // 1. 创建梁板闭合多段线 var beamPolyline = CreateBeamPolyline(startPt, endPt, beamHeight, slabParams); if (beamPolyline == null) throw new SysException("创建梁板多段线失败"); btr.AppendEntity(beamPolyline); tr.AddNewlyCreatedDBObject(beamPolyline, true); // 2. 填充混凝土图案 var hatch = new Hatch(); btr.AppendEntity(hatch); tr.AddNewlyCreatedDBObject(hatch, true); hatch.SetHatchPattern(HatchPatternType.PreDefined, "AR-CONC"); hatch.Associative = true; hatch.AppendLoop(HatchLoopTypes.Outermost, new ObjectIdCollection { beamPolyline.ObjectId }); hatch.PatternScale = 50; // 3. 标注尺寸 CreateDimension(btr, tr, startPt, endPt, beamHeight, slabParams); // 4. 绘制主次龙骨 DrawBeamBottomMembers(btr, tr, beamPolyline, parameters); DrawSlabMembers(btr, tr, beamPolyline, parameters); } private static Polyline CreateBeamPolyline(Point3d start, Point3d end, double height, SlabParams slab) { Vector3d dir = (end - start).GetNormal(); Vector3d perp = new Vector3d(-dir.Y, dir.X, 0) * height; double slabThickness = slab.Thickness; double slabOffset = slab.Offset; var pline = new Polyline(); pline.AddVertexAt(0, new Point2d(start.X, start.Y), 0, 0, 0); pline.AddVertexAt(1, new Point2d(end.X, end.Y), 0, 0, 0); pline.AddVertexAt(2, new Point2d(end.X + perp.X, end.Y + perp.Y), 0, 0, 0); Point3d slabPoint = new Point3d( start.X + perp.X + dir.X * slabOffset, start.Y + perp.Y + dir.Y * slabOffset, 0); pline.AddVertexAt(3, new Point2d(slabPoint.X, slabPoint.Y), 0, 0, 0); Vector3d slabDir = dir * slabThickness; pline.AddVertexAt(4, new Point2d(slabPoint.X + slabDir.X, slabPoint.Y + slabDir.Y), 0, 0, 0); pline.AddVertexAt(5, new Point2d(end.X + slabDir.X, end.Y + slabDir.Y), 0, 0, 0); pline.AddVertexAt(6, new Point2d(start.X + slabDir.X, start.Y + slabDir.Y), 0, 0, 0); pline.Closed = true; return pline; } private static void DrawBeamBottomMembers(BlockTableRecord btr, Transaction tr, Polyline beamPoly, BeamParameters parameters) { double beamLength = beamPoly.Length; // 梁下次龙骨 if (parameters.BeamBottom.SecondaryDirection == "横向") { double spacing = ParseSpacing(parameters.BeamBottom.SecondarySpacing, beamLength); for (double pos = spacing; pos < beamLength; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.BeamBottom.SecondarySpec, 0); } } // 梁下主龙骨 if (parameters.BeamBottom.PrimaryDirection == "横向") { // 横向布置时,使用输入的间距值 if (double.TryParse(parameters.BeamBottom.PrimarySpacing, out double spacing)) { for (double pos = spacing; pos < beamLength; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.BeamBottom.PrimarySpec, 0); } } } else if (parameters.BeamBottom.PrimaryDirection == "纵向") { // 纵向布置时,使用默认间距 double spacing = 1000; // 默认纵向间距 for (double pos = spacing; pos < beamLength; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.BeamBottom.PrimarySpec, 0); } } // 梁侧龙骨(如果启用) if (parameters.BeamSide.Enabled) { // 实现梁侧龙骨绘制逻辑... } } private static void DrawSlabMembers(BlockTableRecord btr, Transaction tr, Polyline beamPoly, BeamParameters parameters) { // 板下次龙骨 if (parameters.Slab.SecondaryDirection == "横向") { double spacing = parameters.Slab.SecondarySpacing; for (double pos = spacing; pos < beamPoly.Length; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.Slab.SecondarySpec, 0); } } // 板下主龙骨 if (parameters.Slab.PrimaryDirection == "横向") { // 横向布置时,使用输入的留空距离值 double spacing = parameters.Slab.PrimarySpacing; for (double pos = spacing; pos < beamPoly.Length - spacing; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.Slab.PrimarySpec, 0); } } else if (parameters.Slab.PrimaryDirection == "纵向") { // 纵向布置时,使用默认间距 double spacing = 1000; // 默认纵向间距 for (double pos = spacing; pos < beamPoly.Length; pos += spacing) { Point3d loc = beamPoly.GetPointAtDist(pos); DrawMemberSection(btr, tr, loc, parameters.Slab.PrimarySpec, 0); } } } private static void DrawMemberSection(BlockTableRecord btr, Transaction tr, Point3d loc, string spec, double angle) { double width = 10, height = 10; ParseMemberSpec(spec, ref width, ref height); var rect = new Polyline(); rect.AddVertexAt(0, new Point2d(loc.X - width / 2, loc.Y - height / 2), 0, 0, 0); rect.AddVertexAt(1, new Point2d(loc.X + width / 2, loc.Y - height / 2), 0, 0, 0); rect.AddVertexAt(2, new Point2d(loc.X + width / 2, loc.Y + height / 2), 0, 0, 0); rect.AddVertexAt(3, new Point2d(loc.X - width / 2, loc.Y + height / 2), 0, 0, 0); rect.Closed = true; if (angle != 0) { Matrix3d rotation = Matrix3d.Rotation(angle, Vector3d.ZAxis, loc); rect.TransformBy(rotation); } btr.AppendEntity(rect); tr.AddNewlyCreatedDBObject(rect, true); } private static void ParseMemberSpec(string spec, ref double width, ref double height) { if (spec.Contains("x") && !spec.Contains("Φ")) { string[] parts = spec.Split('x'); if (parts.Length >= 2) { string wStr = new string(parts[0].Where(c => char.IsDigit(c) || c == '.').ToArray()); string hStr = new string(parts[1].Where(c => char.IsDigit(c) || c == '.').ToArray()); double.TryParse(wStr, out width); double.TryParse(hStr, out height); } } else if (spec.Contains("Φ")) { string diamPart = spec.Split('x')[0].Replace("Φ", ""); string wStr = new string(diamPart.Where(c => char.IsDigit(c) || c == '.').ToArray()); double.TryParse(wStr, out width); height = width; } else if (spec.StartsWith("I")) { string num = new string(spec.Where(char.IsDigit).ToArray()); if (int.TryParse(num, out int size)) { width = size * 0.5; height = size; } } if (width <= 0) width = 10; if (height <= 0) height = 10; } private static double ParseSpacing(string input, double totalLength) { if (input.Contains("@")) { string numPart = new string(input.Replace("@", "").Where(c => char.IsDigit(c) || c == '.').ToArray()); if (double.TryParse(numPart, out double spacing)) return spacing; } else if (input.Contains("根")) { string numPart = new string(input.Where(char.IsDigit).ToArray()); if (int.TryParse(numPart, out int count) && count > 1) return totalLength / (count - 1); } return 200; } private static void CreateDimension(BlockTableRecord btr, Transaction tr, Point3d start, Point3d end, double height, SlabParams slab) { var dimWidth = new AlignedDimension(); dimWidth.SetDatabaseDefaults(); dimWidth.XLine1Point = start; dimWidth.XLine2Point = end; dimWidth.DimLinePoint = new Point3d((start.X + end.X) / 2, start.Y - 50, 0); btr.AppendEntity(dimWidth); tr.AddNewlyCreatedDBObject(dimWidth, true); var dimHeight = new AlignedDimension(); dimHeight.SetDatabaseDefaults(); dimHeight.XLine1Point = start; dimHeight.XLine2Point = new Point3d(start.X, start.Y + height, 0); dimHeight.DimLinePoint = new Point3d(start.X - 50, start.Y + height / 2, 0); btr.AppendEntity(dimHeight); tr.AddNewlyCreatedDBObject(dimHeight, true); var dimSlab = new AlignedDimension(); dimSlab.SetDatabaseDefaults(); dimSlab.XLine1Point = new Point3d(end.X, end.Y + height, 0); dimSlab.XLine2Point = new Point3d(end.X, end.Y + height + slab.Thickness, 0); dimSlab.DimLinePoint = new Point3d(end.X + 50, end.Y + height + slab.Thickness / 2, 0); btr.AppendEntity(dimSlab); tr.AddNewlyCreatedDBObject(dimSlab, true); } } } 还是这个错误:CS0079事件ComboBox.SelectedIndexChanged”只能出现在+=或-=的左边625行
08-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值