Add ToolTip in List/ComboBox Control

Flex应用实例:Bloggers列表
<?xml version=”1.0″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” creationComplete=”initApp()”>
 <mx:Script>
  <![CDATA[
   import mx.collections.ArrayCollection;
   [Bindable]
   private var myDP:ArrayCollection = new ArrayCollection([{name:"Yahoo", blog:"http://www.yahoo.com/"},{name:"Kanu",  blog:"http://kanuwadhwa.wordpress.com"},{name:"Google", blog:"http://www.google.com/"}]);
   [Bindable]
   private var myDropdownFactory:ClassFactory;
   private function initApp():void{
    myDropdownFactory = new ClassFactory(List);
    myDropdownFactory.properties = {showDataTips:true, dataTipFunction:myDataTipFunction}
   }
   private function myDataTipFunction(value:Object):String{
    return (value.name+”’s blog is “+value.blog);
   }
  ]]>
 </mx:Script>
<mx:List id=”myList” dataProvider=”{myDP}” labelField=”name” showDataTips=”true” dataTipFunction=”myDataTipFunction” />
<mx:ComboBox id=”myCB” dataProvider=”{myDP}” labelField=”name” prompt=”Choose a Blogger” dropdownFactory=”{myDropdownFactory}” />
</mx:Application>

 

using System; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Windows.Forms; using WindowsFormsApp1; namespace ScopeCore.Controls { public partial class PopupConditionRule : PopupServiceBase { private List<string> variableList = new List<string>(); private string assembledRule = ""; public event EventHandler<string> RuleChanged; public PopupConditionRule() { InitializeComponent(); flpConditions.AutoScroll = true; btnAddCondition.Click += BtnAddCondition_Click; btnConfirm.Click += BtnConfirm_Click; btnCancel.Click += BtnCancel_Click; tbDuration.TextChanged += TbDuration_TextChanged; // 初始至少一行 AddConditionRow(); } public void SetVariables(List<string> vars) { variableList = vars ?? new List<string>(); // 将已有行更新变量列表 foreach (Control c in flpConditions.Controls) { ConditionRowControl row = c as ConditionRowControl; if (row != null) row.SetVariableList(variableList); } } public void SetRule(string rule) { if (string.IsNullOrEmpty(rule)) { // 清空,保留一行 flpConditions.Controls.Clear(); AddConditionRow(); assembledRule = ""; return; } // 解析原始规则,拆出原子比较与逻辑符 List<string> atomics = new List<string>(); List<string> logics = new List<string>(); // 正则提取所有形如 "( ... op ... )" 的原子条件(最小括号级) // 这里假定每个原子比较都被括号包裹,例如: ( /IO/... == Shuttered ) Regex atomRegex = new Regex(@"\(\s*([^()]+?\s*(==|!=|<=|>=|<|>)\s*[^()]+?)\s*\)"); MatchCollection matches = atomRegex.Matches(rule); foreach (Match m in matches) { atomics.Add(m.Groups[1].Value.Trim()); } // 提取 atomics 之间的逻辑操作符顺序(扫描原字符串,查找 && 或 ||) // 找到每个原子在字符串中的位置,然后在两个原子之间搜索逻辑符 int idx = 0; for (int i = 0; i < atomics.Count; i++) { // find position of this atomic (first occurrence after idx) string atomicPattern = @"\(\s*" + Regex.Escape(atomics[i]) + @"\s*\)"; Match m = Regex.Match(rule, atomicPattern); if (m.Success) { idx = m.Index + m.Length; // look ahead for next logic if there is next atomic if (i + 1 < atomics.Count) { // search between end of this atomic and start of next atomic string nextAtomicPattern = @"\(\s*" + Regex.Escape(atomics[i + 1]) + @"\s*\)"; Match nextM = Regex.Match(rule, nextAtomicPattern); if (nextM.Success && nextM.Index > idx) { string between = rule.Substring(idx, nextM.Index - idx); // find first && or || Match logicM = Regex.Match(between, @"(&&|\|\|)"); if (logicM.Success) logics.Add(logicM.Value); else logics.Add("&&"); // default } else { logics.Add("&&"); } } } } // 清空当前行,逐个生成条件行 flpConditions.Controls.Clear(); for (int i = 0; i < atomics.Count; i++) { // atomics[i] 形如 "VarName == Value" string atomic = atomics[i]; // 解析 variable, operator, value Regex parts = new Regex(@"^\s*([^=<>!\s]+?)\s*(==|!=|<=|>=|<|>)\s*(.+)\s*$"); Match pm = parts.Match(atomic); string var = "", op = "==", val = ""; if (pm.Success) { var = pm.Groups[1].Value.Trim(); op = pm.Groups[2].Value.Trim(); val = pm.Groups[3].Value.Trim(); } ConditionRowControl row = CreateConditionRow(); row.SetVariableList(variableList); string logic = (i < logics.Count) ? logics[i] : "&&"; row.SetCondition(var, op, val, logic); flpConditions.Controls.Add(row); } if (atomics.Count == 0) { // 解析失败或空:保留一行 AddConditionRow(); } UpdateLogicVisibility(); RebuildRuleAndRaiseEvent(); } private void TbDuration_TextChanged(object sender, EventArgs e) { // 基本校验:非空且为非负整数 string txt = tbDuration.Text.Trim(); string err = ""; if (string.IsNullOrEmpty(txt)) { err = "Duration 不能为空(毫秒)。"; } else { int v; if (!int.TryParse(txt, out v) || v < 0) { err = "Duration 必须为非负整数(毫秒)。"; } } errorProvider1.SetError(tbDuration, err); } private void BtnAddCondition_Click(object sender, EventArgs e) { AddConditionRow(); } private void AddConditionRow() { ConditionRowControl row = CreateConditionRow(); row.SetVariableList(variableList); flpConditions.Controls.Add(row); UpdateLogicVisibility(); RebuildRuleAndRaiseEvent(); } private ConditionRowControl CreateConditionRow() { ConditionRowControl row = new ConditionRowControl(); row.DeleteClicked += (s, e) => { flpConditions.Controls.Remove(row); UpdateLogicVisibility(); RebuildRuleAndRaiseEvent(); }; row.ValueChanged += (s, e) => { RebuildRuleAndRaiseEvent(); }; return row; } private void UpdateLogicVisibility() { // 所有行的 Logic 可见,但最后一行隐藏 Logic for (int i = 0; i < flpConditions.Controls.Count; i++) { ConditionRowControl row = flpConditions.Controls[i] as ConditionRowControl; if (row != null) { row.SetLogicVisible(i != flpConditions.Controls.Count - 1); } } } private void BtnConfirm_Click(object sender, EventArgs e) { // 验证每行 value 非空 foreach (Control c in flpConditions.Controls) { ConditionRowControl row = c as ConditionRowControl; if (row != null) { string val = row.GetValue(); if (string.IsNullOrEmpty(val)) { MessageBox.Show("每行的 Value 不允许为空,请填写。", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 对数值类型可以额外验证范围 var desc = DataManager.GetIns().GetItemValue(row.GetVariable()); if (desc is DataManager.DoubleInfo) { double v; if (!double.TryParse(val, out v)) { MessageBox.Show("数值格式错误,请输入合法数字。", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } DataManager.DoubleInfo di = (DataManager.DoubleInfo)desc; if (v < di.Min || v > di.Max) { MessageBox.Show(string.Format("数值超出范围 {0} - {1}。", di.Min, di.Max), "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } } } // Duration 验证 string durText = tbDuration.Text.Trim(); if (!string.IsNullOrEmpty(durText)) { int dv; if (!int.TryParse(durText, out dv) || dv < 0) { MessageBox.Show("Duration 必须为非负整数(毫秒)。", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } // 组装字符串 assembledRule = BuildRuleString(); this.DialogResult = DialogResult.OK; this.Close(); } private void BtnCancel_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.Cancel; this.Close(); } private string BuildRuleString() { // 将每个原子包成 (var op val),并用逻辑符将它们连接起来,用额外 () 包裹整体,并在末尾追加 Duration(ms)(如果有) List<string> parts = new List<string>(); for (int i = 0; i < flpConditions.Controls.Count; i++) { ConditionRowControl row = flpConditions.Controls[i] as ConditionRowControl; if (row != null) { string var = row.GetVariable(); string op = row.GetOperator(); string val = row.GetValue(); parts.Add("(" + var + " " + op + " " + val + ")"); } } // 连接时每两个项之间用对应行的 Logic(第 i 项与第 i+1 项之间使用第 i 项的 Logic) if (parts.Count == 0) return ""; string joined = parts[0]; for (int i = 0; i < parts.Count - 1; i++) { ConditionRowControl row = flpConditions.Controls[i] as ConditionRowControl; string logic = (row != null) ? row.GetLogic() : "&&"; joined = "(" + joined + logic + parts[i + 1] + ")"; } // 末尾 Duration string durText = tbDuration.Text.Trim(); if (!string.IsNullOrEmpty(durText)) { joined = joined + " " + durText + "(ms)"; } return joined; } private void RebuildRuleAndRaiseEvent() { string ru = BuildRuleString(); assembledRule = ru; RuleChanged?.Invoke(this, assembledRule); } public string GetRule() { return assembledRule; } } } ConditionRowControl.cs using System; using System.Collections.Generic; using System.Windows.Forms; namespace ScopeCore.Controls { public partial class ConditionRowControl : UserControl { public event EventHandler DeleteClicked; public event EventHandler ValueChanged; public ConditionRowControl() { InitializeComponent(); // 操作符 cbOperator.Items.AddRange(new object[] { "==", "!=", "<", "<=", ">", ">=" }); cbLogic.Items.AddRange(new object[] { "&&", "||" }); cbVariable.SelectedIndexChanged += cbVariable_SelectedIndexChanged; cbOperator.SelectedIndexChanged += (s, e) => OnValueChanged(); cbLogic.SelectedIndexChanged += (s, e) => OnValueChanged(); btnDelete.Click += (s, e) => DeleteClicked?.Invoke(this, EventArgs.Empty); } public void SetVariableList(List<string> vars) { cbVariable.Items.Clear(); foreach (string v in vars) cbVariable.Items.Add(v); if (cbVariable.Items.Count > 0 && cbVariable.SelectedIndex < 0) cbVariable.SelectedIndex = 0; } public void SetCondition(string variable, string oper, string value, string logic) { if (!string.IsNullOrEmpty(variable) && cbVariable.Items.Contains(variable)) cbVariable.SelectedItem = variable; else if (cbVariable.Items.Count > 0) cbVariable.SelectedIndex = 0; if (!string.IsNullOrEmpty(oper) && cbOperator.Items.Contains(oper)) cbOperator.SelectedItem = oper; else cbOperator.SelectedIndex = 0; // 触发变量切换后会设置 Value 控件类型 ApplyValueAccordingToVariable(); SetValueText(value); if (!string.IsNullOrEmpty(logic) && cbLogic.Items.Contains(logic)) cbLogic.SelectedItem = logic; else cbLogic.SelectedIndex = 0; } private void cbVariable_SelectedIndexChanged(object sender, EventArgs e) { ApplyValueAccordingToVariable(); OnValueChanged(); } private void ApplyValueAccordingToVariable() { string varName = GetVariable(); var desc = DataManager.GetIns().GetItemValue(varName); // 如果返回 string[] 则为枚举 if (desc is string[]) { // 显示 ComboBox 做为 Value if (!(valueCombo.Visible)) { valueText.Visible = false; valueCombo.Visible = true; } valueCombo.Items.Clear(); string[] opts = desc as string[]; foreach (string o in opts) valueCombo.Items.Add(o); if (valueCombo.Items.Count > 0) valueCombo.SelectedIndex = 0; } else if (desc is DataManager.DoubleInfo) { // 数值,显示 TextBox valueCombo.Visible = false; valueText.Visible = true; // 可根据 DoubleInfo.min/max 做 placeholder 或 tooltip DataManager.DoubleInfo di = (DataManager.DoubleInfo)desc; valueText.Tag = string.Format("范围 {0} - {1}", di.Min, di.Max); } else // string 类型 { valueCombo.Visible = false; valueText.Visible = true; valueText.Tag = "字符串"; } } public string GetVariable() { if (cbVariable.SelectedItem == null) return ""; return cbVariable.SelectedItem.ToString(); } public string GetOperator() { if (cbOperator.SelectedItem == null) return ""; return cbOperator.SelectedItem.ToString(); } public string GetValue() { if (valueCombo.Visible) return valueCombo.Text.Trim(); return valueText.Text.Trim(); } public string GetLogic() { if (cbLogic.SelectedItem == null) return "&&"; return cbLogic.SelectedItem.ToString(); } public void SetLogicVisible(bool visible) { cbLogic.Visible = visible; } public void SetValueText(string v) { if (valueCombo.Visible) { if (valueCombo.Items.Contains(v)) valueCombo.SelectedItem = v; else if (valueCombo.Items.Count > 0) valueCombo.SelectedIndex = 0; } else { valueText.Text = v ?? ""; } } protected void OnValueChanged() { ValueChanged?.Invoke(this, EventArgs.Empty); } } } 控件数目不是空,但是没有被显示在窗口中。
11-18
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using System; using System.Collections.Generic; using System.Windows.Forms; using System.Drawing; namespace BeamSlabPlugin { // 参数类定义 public class BeamSlabParameters { public BeamSideSecondaryParameters BeamSideSecondary { get; set; } = new BeamSideSecondaryParameters(); public BeamSidePrimaryParameters BeamSidePrimary { get; set; } = new BeamSidePrimaryParameters(); public BeamBoltParameters BeamBolt { get; set; } = new BeamBoltParameters(); public BeamBottomSecondaryParameters BeamBottomSecondary { get; set; } = new BeamBottomSecondaryParameters(); public BeamBottomPrimaryParameters BeamBottomPrimary { get; set; } = new BeamBottomPrimaryParameters(); public SlabParameters Slab { get; set; } = new SlabParameters(); public double DefaultSlabThickness { get; set; } = 120; public double FormworkThickness { get; set; } = 15; } public class BeamSideSecondaryParameters { public bool Enabled { get; set; } = true; public string Direction { get; set; } = "Vertical"; public string Material { get; set; } = "木方"; public double Height { get; set; } = 90; public double Width { get; set; } = 40; public double Spacing { get; set; } = 200; } public class BeamSidePrimaryParameters { public bool Enabled { get; set; } = true; public string Direction { get; set; } = "Horizontal"; public string Material { get; set; } = "钢管"; public double Height { get; set; } = 100; public double Width { get; set; } = 100; public double Diameter { get; set; } = 48; } public class BeamBoltParameters { public bool Enabled { get; set; } = true; public double BottomOffset { get; set; } = 150; public double TopOffset { get; set; } = 150; public double MaxSpacing { get; set; } = 500; } public class BeamBottomSecondaryParameters { public bool Enabled { get; set; } = true; public string Direction { get; set; } = "Longitudinal"; public string Material { get; set; } = "木方"; public double Height { get; set; } = 90; public double Width { get; set; } = 40; public double Spacing { get; set; } = 200; } public class BeamBottomPrimaryParameters { public bool Enabled { get; set; } = true; public string Material { get; set; } = "钢管"; public double Height { get; set; } = 100; public double Width { get; set; } = 100; } public class SlabParameters { public bool SecondaryEnabled { get; set; } = true; public string SecondaryDirection { get; set; } = "Longitudinal"; public string SecondaryMaterial { get; set; } = "木方"; public double SecondaryHeight { get; set; } = 90; public double SecondaryWidth { get; set; } = 40; public double SecondarySpacing { get; set; } = 200; public bool PrimaryEnabled { get; set; } = true; public string PrimaryMaterial { get; set; } = "钢管"; public double PrimaryHeight { get; set; } = 100; public double PrimaryWidth { get; set; } = 100; } // 参数窗体类 public class ParameterForm : Form { public BeamSlabParameters Parameters { get; private set; } // 梁侧次龙骨控件 private RadioButton radBeamSideSecondaryYes; private RadioButton radBeamSideSecondaryNo; private RadioButton radBeamSideSecondaryHorizontal; private RadioButton radBeamSideSecondaryVertical; private ComboBox cmbBeamSideSecondaryMaterial; private TextBox txtBeamSideSecondaryHeight; private TextBox txtBeamSideSecondaryWidth; private TextBox txtBeamSideSecondarySpacing; // 梁侧主龙骨控件 private RadioButton radBeamSidePrimaryYes; private RadioButton radBeamSidePrimaryNo; private RadioButton radBeamSidePrimaryHorizontal; private RadioButton radBeamSidePrimaryVertical; private ComboBox cmbBeamSidePrimaryMaterial; private TextBox txtBeamSidePrimaryHeight; private TextBox txtBeamSidePrimaryWidth; private TextBox txtBeamSidePrimaryDiameter; // 梁对拉螺栓设置控件 private TextBox txtBeamBoltBottomOffset; private TextBox txtBeamBoltTopOffset; private TextBox txtBeamBoltMaxSpacing; // 梁底次龙骨控件 private RadioButton radBeamBottomSecondaryYes; private RadioButton radBeamBottomSecondaryNo; private RadioButton radBeamBottomSecondaryHorizontal; private RadioButton radBeamBottomSecondaryLongitudinal; private ComboBox cmbBeamBottomSecondaryMaterial; private TextBox txtBeamBottomSecondaryHeight; private TextBox txtBeamBottomSecondaryWidth; private TextBox txtBeamBottomSecondarySpacing; // 梁底主龙骨控件 private RadioButton radBeamBottomPrimaryYes; private RadioButton radBeamBottomPrimaryNo; private ComboBox cmbBeamBottomPrimaryMaterial; private TextBox txtBeamBottomPrimaryHeight; private TextBox txtBeamBottomPrimaryWidth; // 板龙骨设置控件 private TextBox txtDefaultSlabThickness; private TextBox txtFormworkThickness; private RadioButton radSlabSecondaryYes; private RadioButton radSlabSecondaryNo; private RadioButton radSlabSecondaryHorizontal; private RadioButton radSlabSecondaryLongitudinal; private ComboBox cmbSlabSecondaryMaterial; private TextBox txtSlabSecondaryHeight; private TextBox txtSlabSecondaryWidth; private TextBox txtSlabSecondarySpacing; private RadioButton radSlabPrimaryYes; private RadioButton radSlabPrimaryNo; private ComboBox cmbSlabPrimaryMaterial; private TextBox txtSlabPrimaryHeight; private TextBox txtSlabPrimaryWidth; private Button btnOK; private Button btnCancel; public ParameterForm() { Parameters = new BeamSlabParameters(); InitializeComponent(); SetupEventHandlers(); } private void InitializeComponent() { this.Text = "梁板剖面绘制参数设置"; this.Size = new Size(800, 600); // 增加窗体大小以容纳所有控件 this.StartPosition = FormStartPosition.CenterScreen; this.FormBorderStyle = FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; // 创建选项卡控件 TabControl tabControl = new TabControl(); tabControl.Dock = DockStyle.Fill; tabControl.TabPages.Add("梁龙骨设置"); tabControl.TabPages.Add("板龙骨设置"); // 梁龙骨设置页面 TabPage beamPage = tabControl.TabPages[0]; beamPage.AutoScroll = true; // 启用滚动条 InitializeBeamPage(beamPage); // 板龙骨设置页面 TabPage slabPage = tabControl.TabPages[1]; slabPage.AutoScroll = true; // 启用滚动条 InitializeSlabPage(slabPage); // 创建底部面板放置按钮 Panel bottomPanel = new Panel(); bottomPanel.Dock = DockStyle.Bottom; bottomPanel.Height = 50; bottomPanel.BackColor = SystemColors.Control; // 确定和取消按钮 btnOK = new Button(); btnOK.Text = "开始绘制"; btnOK.DialogResult = DialogResult.OK; btnOK.Size = new Size(100, 30); btnOK.Location = new Point(this.Width - 220, 10); btnCancel = new Button(); btnCancel.Text = "取消"; btnCancel.DialogResult = DialogResult.Cancel; btnCancel.Size = new Size(100, 30); btnCancel.Location = new Point(this.Width - 110, 10); bottomPanel.Controls.Add(btnOK); bottomPanel.Controls.Add(btnCancel); this.Controls.Add(tabControl); this.Controls.Add(bottomPanel); } private void InitializeBeamPage(TabPage page) { int yPos = 15; int labelWidth = 120; int controlSpacing = 10; int column1 = 20; int column2 = column1 + labelWidth + controlSpacing; int column3 = column2 + 100; int column4 = column3 + 100; int column5 = column4 + 100; // 标题 Label lblTitle = new Label(); lblTitle.Text = "梁龙骨设置参数"; lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 10, System.Drawing.FontStyle.Bold); lblTitle.Location = new Point(column1, yPos); lblTitle.Size = new Size(250, 20); page.Controls.Add(lblTitle); yPos += 30; // 绘制梁侧次龙骨 Label lblBeamSideSecondary = new Label(); lblBeamSideSecondary.Text = "绘制梁侧次龙骨:"; lblBeamSideSecondary.Location = new Point(column1, yPos); lblBeamSideSecondary.Size = new Size(labelWidth, 20); page.Controls.Add(lblBeamSideSecondary); radBeamSideSecondaryYes = new RadioButton(); radBeamSideSecondaryYes.Text = "是"; radBeamSideSecondaryYes.Checked = true; radBeamSideSecondaryYes.Location = new Point(column2, yPos); radBeamSideSecondaryYes.Size = new Size(40, 20); page.Controls.Add(radBeamSideSecondaryYes); radBeamSideSecondaryNo = new RadioButton(); radBeamSideSecondaryNo.Text = "否"; radBeamSideSecondaryNo.Location = new Point(column2 + 50, yPos); radBeamSideSecondaryNo.Size = new Size(40, 20); page.Controls.Add(radBeamSideSecondaryNo); // 绘制方向 Label lblDirection = new Label(); lblDirection.Text = "绘制方向:"; lblDirection.Location = new Point(column3, yPos); lblDirection.Size = new Size(70, 20); page.Controls.Add(lblDirection); radBeamSideSecondaryHorizontal = new RadioButton(); radBeamSideSecondaryHorizontal.Text = "横向"; radBeamSideSecondaryHorizontal.Location = new Point(column3 + 80, yPos); radBeamSideSecondaryHorizontal.Size = new Size(50, 20); page.Controls.Add(radBeamSideSecondaryHorizontal); radBeamSideSecondaryVertical = new RadioButton(); radBeamSideSecondaryVertical.Text = "竖向"; radBeamSideSecondaryVertical.Location = new Point(column3 + 140, yPos); radBeamSideSecondaryVertical.Size = new Size(50, 20); radBeamSideSecondaryVertical.Checked = true; page.Controls.Add(radBeamSideSecondaryVertical); // 材料 Label lblMaterial = new Label(); lblMaterial.Text = "材料:"; lblMaterial.Location = new Point(column4, yPos); lblMaterial.Size = new Size(50, 20); page.Controls.Add(lblMaterial); cmbBeamSideSecondaryMaterial = new ComboBox(); cmbBeamSideSecondaryMaterial.Items.AddRange(new object[] { "木方", "方钢", "钢管" }); cmbBeamSideSecondaryMaterial.SelectedIndex = 0; cmbBeamSideSecondaryMaterial.Location = new Point(column4 + 50, yPos); cmbBeamSideSecondaryMaterial.Size = new Size(80, 20); page.Controls.Add(cmbBeamSideSecondaryMaterial); yPos += 30; // 规格 Label lblSpec = new Label(); lblSpec.Text = "规格:"; lblSpec.Location = new Point(column2, yPos); lblSpec.Size = new Size(40, 20); page.Controls.Add(lblSpec); Label lblHeight = new Label(); lblHeight.Text = "高:"; lblHeight.Location = new Point(column2 + 50, yPos); lblHeight.Size = new Size(30, 20); page.Controls.Add(lblHeight); txtBeamSideSecondaryHeight = new TextBox(); txtBeamSideSecondaryHeight.Text = "90"; txtBeamSideSecondaryHeight.Location = new Point(column2 + 80, yPos); txtBeamSideSecondaryHeight.Size = new Size(50, 20); page.Controls.Add(txtBeamSideSecondaryHeight); Label lblWidth = new Label(); lblWidth.Text = "宽:"; lblWidth.Location = new Point(column2 + 140, yPos); lblWidth.Size = new Size(30, 20); page.Controls.Add(lblWidth); txtBeamSideSecondaryWidth = new TextBox(); txtBeamSideSecondaryWidth.Text = "40"; txtBeamSideSecondaryWidth.Location = new Point(column2 + 170, yPos); txtBeamSideSecondaryWidth.Size = new Size(50, 20); page.Controls.Add(txtBeamSideSecondaryWidth); Label lblSpacing = new Label(); lblSpacing.Text = "间距:"; lblSpacing.Location = new Point(column2 + 230, yPos); lblSpacing.Size = new Size(40, 20); page.Controls.Add(lblSpacing); txtBeamSideSecondarySpacing = new TextBox(); txtBeamSideSecondarySpacing.Text = "200"; txtBeamSideSecondarySpacing.Location = new Point(column2 + 270, yPos); txtBeamSideSecondarySpacing.Size = new Size(50, 20); page.Controls.Add(txtBeamSideSecondarySpacing); yPos += 40; // 绘制梁侧主龙骨 Label lblBeamSidePrimary = new Label(); lblBeamSidePrimary.Text = "绘制梁侧主龙骨:"; lblBeamSidePrimary.Location = new Point(column1, yPos); lblBeamSidePrimary.Size = new Size(labelWidth, 20); page.Controls.Add(lblBeamSidePrimary); radBeamSidePrimaryYes = new RadioButton(); radBeamSidePrimaryYes.Text = "是"; radBeamSidePrimaryYes.Checked = true; radBeamSidePrimaryYes.Location = new Point(column2, yPos); radBeamSidePrimaryYes.Size = new Size(40, 20); page.Controls.Add(radBeamSidePrimaryYes); radBeamSidePrimaryNo = new RadioButton(); radBeamSidePrimaryNo.Text = "否"; radBeamSidePrimaryNo.Location = new Point(column2 + 50, yPos); radBeamSidePrimaryNo.Size = new Size(40, 20); page.Controls.Add(radBeamSidePrimaryNo); // 绘制方向 Label lblDirection2 = new Label(); lblDirection2.Text = "绘制方向:"; lblDirection2.Location = new Point(column3, yPos); lblDirection2.Size = new Size(70, 20); page.Controls.Add(lblDirection2); radBeamSidePrimaryHorizontal = new RadioButton(); radBeamSidePrimaryHorizontal.Text = "横向"; radBeamSidePrimaryHorizontal.Location = new Point(column3 + 80, yPos); radBeamSidePrimaryHorizontal.Size = new Size(50, 20); radBeamSidePrimaryHorizontal.Checked = true; page.Controls.Add(radBeamSidePrimaryHorizontal); radBeamSidePrimaryVertical = new RadioButton(); radBeamSidePrimaryVertical.Text = "竖向"; radBeamSidePrimaryVertical.Location = new Point(column3 + 140, yPos); radBeamSidePrimaryVertical.Size = new Size(50, 20); page.Controls.Add(radBeamSidePrimaryVertical); // 材料 Label lblMaterial2 = new Label(); lblMaterial2.Text = "材料:"; lblMaterial2.Location = new Point(column4, yPos); lblMaterial2.Size = new Size(50, 20); page.Controls.Add(lblMaterial2); cmbBeamSidePrimaryMaterial = new ComboBox(); cmbBeamSidePrimaryMaterial.Items.AddRange(new object[] { "木方", "方钢", "钢管" }); cmbBeamSidePrimaryMaterial.SelectedIndex = 2; cmbBeamSidePrimaryMaterial.Location = new Point(column4 + 50, yPos); cmbBeamSidePrimaryMaterial.Size = new Size(80, 20); page.Controls.Add(cmbBeamSidePrimaryMaterial); yPos += 30; // 规格 Label lblSpec2 = new Label(); lblSpec2.Text = "规格:"; lblSpec2.Location = new Point(column2, yPos); lblSpec2.Size = new Size(40, 20); page.Controls.Add(lblSpec2); Label lblHeight2 = new Label(); lblHeight2.Text = "高:"; lblHeight2.Location = new Point(column2 + 50, yPos); lblHeight2.Size = new Size(30, 20); page.Controls.Add(lblHeight2); txtBeamSidePrimaryHeight = new TextBox(); txtBeamSidePrimaryHeight.Text = "100"; txtBeamSidePrimaryHeight.Location = new Point(column2 + 80, yPos); txtBeamSidePrimaryHeight.Size = new Size(50, 20); page.Controls.Add(txtBeamSidePrimaryHeight); Label lblWidth2 = new Label(); lblWidth2.Text = "宽:"; lblWidth2.Location = new Point(column2 + 140, yPos); lblWidth2.Size = new Size(30, 20); page.Controls.Add(lblWidth2); txtBeamSidePrimaryWidth = new TextBox(); txtBeamSidePrimaryWidth.Text = "100"; txtBeamSidePrimaryWidth.Location = new Point(column2 + 170, yPos); txtBeamSidePrimaryWidth.Size = new Size(50, 20); page.Controls.Add(txtBeamSidePrimaryWidth); Label lblDiameter = new Label(); lblDiameter.Text = "直径:"; lblDiameter.Location = new Point(column2 + 230, yPos); lblDiameter.Size = new Size(40, 20); page.Controls.Add(lblDiameter); txtBeamSidePrimaryDiameter = new TextBox(); txtBeamSidePrimaryDiameter.Text = "48"; txtBeamSidePrimaryDiameter.Location = new Point(column2 + 270, yPos); txtBeamSidePrimaryDiameter.Size = new Size(50, 20); page.Controls.Add(txtBeamSidePrimaryDiameter); yPos += 40; // 梁对拉螺栓设置 Label lblBeamBolt = new Label(); lblBeamBolt.Text = "梁对拉螺栓设置:"; lblBeamBolt.Location = new Point(column1, yPos); lblBeamBolt.Size = new Size(labelWidth, 20); page.Controls.Add(lblBeamBolt); Label lblBottomOffset = new Label(); lblBottomOffset.Text = "底第一道螺栓离梁底高:"; lblBottomOffset.Location = new Point(column2, yPos); lblBottomOffset.Size = new Size(150, 20); page.Controls.Add(lblBottomOffset); txtBeamBoltBottomOffset = new TextBox(); txtBeamBoltBottomOffset.Text = "150"; txtBeamBoltBottomOffset.Location = new Point(column2 + 160, yPos); txtBeamBoltBottomOffset.Size = new Size(50, 20); page.Controls.Add(txtBeamBoltBottomOffset); Label lblTopOffset = new Label(); lblTopOffset.Text = "顶第一道螺栓离板底高:"; lblTopOffset.Location = new Point(column3, yPos); lblTopOffset.Size = new Size(150, 20); page.Controls.Add(lblTopOffset); txtBeamBoltTopOffset = new TextBox(); txtBeamBoltTopOffset.Text = "150"; txtBeamBoltTopOffset.Location = new Point(column3 + 160, yPos); txtBeamBoltTopOffset.Size = new Size(50, 20); page.Controls.Add(txtBeamBoltTopOffset); yPos += 30; Label lblMaxSpacing = new Label(); lblMaxSpacing.Text = "螺栓最大间距:"; lblMaxSpacing.Location = new Point(column2, yPos); lblMaxSpacing.Size = new Size(100, 20); page.Controls.Add(lblMaxSpacing); txtBeamBoltMaxSpacing = new TextBox(); txtBeamBoltMaxSpacing.Text = "500"; txtBeamBoltMaxSpacing.Location = new Point(column2 + 110, yPos); txtBeamBoltMaxSpacing.Size = new Size(50, 20); page.Controls.Add(txtBeamBoltMaxSpacing); yPos += 40; // 绘制梁底次龙骨 Label lblBeamBottomSecondary = new Label(); lblBeamBottomSecondary.Text = "绘制梁底次龙骨:"; lblBeamBottomSecondary.Location = new Point(column1, yPos); lblBeamBottomSecondary.Size = new Size(labelWidth, 20); page.Controls.Add(lblBeamBottomSecondary); radBeamBottomSecondaryYes = new RadioButton(); radBeamBottomSecondaryYes.Text = "是"; radBeamBottomSecondaryYes.Checked = true; radBeamBottomSecondaryYes.Location = new Point(column2, yPos); radBeamBottomSecondaryYes.Size = new Size(40, 20); page.Controls.Add(radBeamBottomSecondaryYes); radBeamBottomSecondaryNo = new RadioButton(); radBeamBottomSecondaryNo.Text = "否"; radBeamBottomSecondaryNo.Location = new Point(column2 + 50, yPos); radBeamBottomSecondaryNo.Size = new Size(40, 20); page.Controls.Add(radBeamBottomSecondaryNo); // 绘制方向 Label lblDirection3 = new Label(); lblDirection3.Text = "绘制方向:"; lblDirection3.Location = new Point(column3, yPos); lblDirection3.Size = new Size(70, 20); page.Controls.Add(lblDirection3); radBeamBottomSecondaryHorizontal = new RadioButton(); radBeamBottomSecondaryHorizontal.Text = "横向"; radBeamBottomSecondaryHorizontal.Location = new Point(column3 + 80, yPos); radBeamBottomSecondaryHorizontal.Size = new Size(50, 20); page.Controls.Add(radBeamBottomSecondaryHorizontal); radBeamBottomSecondaryLongitudinal = new RadioButton(); radBeamBottomSecondaryLongitudinal.Text = "纵向"; radBeamBottomSecondaryLongitudinal.Location = new Point(column3 + 140, yPos); radBeamBottomSecondaryLongitudinal.Size = new Size(50, 20); radBeamBottomSecondaryLongitudinal.Checked = true; page.Controls.Add(radBeamBottomSecondaryLongitudinal); // 材料 Label lblMaterial3 = new Label(); lblMaterial3.Text = "材料:"; lblMaterial3.Location = new Point(column4, yPos); lblMaterial3.Size = new Size(50, 20); page.Controls.Add(lblMaterial3); cmbBeamBottomSecondaryMaterial = new ComboBox(); cmbBeamBottomSecondaryMaterial.Items.AddRange(new object[] { "木方", "方钢", "钢管" }); cmbBeamBottomSecondaryMaterial.SelectedIndex = 0; cmbBeamBottomSecondaryMaterial.Location = new Point(column4 + 50, yPos); cmbBeamBottomSecondaryMaterial.Size = new Size(80, 20); page.Controls.Add(cmbBeamBottomSecondaryMaterial); yPos += 30; // 规格 Label lblSpec3 = new Label(); lblSpec3.Text = "规格:"; lblSpec3.Location = new Point(column2, yPos); lblSpec3.Size = new Size(40, 20); page.Controls.Add(lblSpec3); Label lblHeight3 = new Label(); lblHeight3.Text = "高:"; lblHeight3.Location = new Point(column2 + 50, yPos); lblHeight3.Size = new Size(30, 20); page.Controls.Add(lblHeight3); txtBeamBottomSecondaryHeight = new TextBox(); txtBeamBottomSecondaryHeight.Text = "90"; txtBeamBottomSecondaryHeight.Location = new Point(column2 + 80, yPos); txtBeamBottomSecondaryHeight.Size = new Size(50, 20); page.Controls.Add(txtBeamBottomSecondaryHeight); Label lblWidth3 = new Label(); lblWidth3.Text = "宽:"; lblWidth3.Location = new Point(column2 + 140, yPos); lblWidth3.Size = new Size(30, 20); page.Controls.Add(lblWidth3); txtBeamBottomSecondaryWidth = new TextBox(); txtBeamBottomSecondaryWidth.Text = "40"; txtBeamBottomSecondaryWidth.Location = new Point(column2 + 170, yPos); txtBeamBottomSecondaryWidth.Size = new Size(50, 20); page.Controls.Add(txtBeamBottomSecondaryWidth); Label lblSpacing3 = new Label(); lblSpacing3.Text = "间距:"; lblSpacing3.Location = new Point(column2 + 230, yPos); lblSpacing3.Size = new Size(40, 20); page.Controls.Add(lblSpacing3); txtBeamBottomSecondarySpacing = new TextBox(); txtBeamBottomSecondarySpacing.Text = "200"; txtBeamBottomSecondarySpacing.Location = new Point(column2 + 270, yPos); txtBeamBottomSecondarySpacing.Size = new Size(50, 20); page.Controls.Add(txtBeamBottomSecondarySpacing); yPos += 40; // 绘制梁底主龙骨 Label lblBeamBottomPrimary = new Label(); lblBeamBottomPrimary.Text = "绘制梁底主龙骨:"; lblBeamBottomPrimary.Location = new Point(column1, yPos); lblBeamBottomPrimary.Size = new Size(labelWidth, 20); page.Controls.Add(lblBeamBottomPrimary); radBeamBottomPrimaryYes = new RadioButton(); radBeamBottomPrimaryYes.Text = "是"; radBeamBottomPrimaryYes.Checked = true; radBeamBottomPrimaryYes.Location = new Point(column2, yPos); radBeamBottomPrimaryYes.Size = new Size(40, 20); page.Controls.Add(radBeamBottomPrimaryYes); radBeamBottomPrimaryNo = new RadioButton(); radBeamBottomPrimaryNo.Text = "否"; radBeamBottomPrimaryNo.Location = new Point(column2 + 50, yPos); radBeamBottomPrimaryNo.Size = new Size(40, 20); page.Controls.Add(radBeamBottomPrimaryNo); // 材料 Label lblMaterial4 = new Label(); lblMaterial4.Text = "材料:"; lblMaterial4.Location = new Point(column3, yPos); lblMaterial4.Size = new Size(50, 20); page.Controls.Add(lblMaterial4); cmbBeamBottomPrimaryMaterial = new ComboBox(); cmbBeamBottomPrimaryMaterial.Items.AddRange(new object[] { "木方", "方钢", "钢管" }); cmbBeamBottomPrimaryMaterial.SelectedIndex = 2; cmbBeamBottomPrimaryMaterial.Location = new Point(column3 + 50, yPos); cmbBeamBottomPrimaryMaterial.Size = new Size(80, 20); page.Controls.Add(cmbBeamBottomPrimaryMaterial); yPos += 30; // 规格 Label lblSpec4 = new Label(); lblSpec4.Text = "规格:"; lblSpec4.Location = new Point(column2, yPos); lblSpec4.Size = new Size(40, 20); page.Controls.Add(lblSpec4); Label lblHeight4 = new Label(); lblHeight4.Text = "高:"; lblHeight4.Location = new Point(column2 + 50, yPos); lblHeight4.Size = new Size(30, 20); page.Controls.Add(lblHeight4); txtBeamBottomPrimaryHeight = new TextBox(); txtBeamBottomPrimaryHeight.Text = "100"; txtBeamBottomPrimaryHeight.Location = new Point(column2 + 80, yPos); txtBeamBottomPrimaryHeight.Size = new Size(50, 20); page.Controls.Add(txtBeamBottomPrimaryHeight); Label lblWidth4 = new Label(); lblWidth4.Text = "宽:"; lblWidth4.Location = new Point(column2 + 140, yPos); lblWidth4.Size = new Size(30, 20); page.Controls.Add(lblWidth4); txtBeamBottomPrimaryWidth = new TextBox(); txtBeamBottomPrimaryWidth.Text = "100"; txtBeamBottomPrimaryWidth.Location = new Point(column2 + 170, yPos); txtBeamBottomPrimaryWidth.Size = new Size(50, 20); page.Controls.Add(txtBeamBottomPrimaryWidth); } private void InitializeSlabPage(TabPage page) { int yPos = 15; int labelWidth = 120; int controlSpacing = 10; int column1 = 20; int column2 = column1 + labelWidth + controlSpacing; int column3 = column2 + 100; int column4 = column3 + 100; // 标题 Label lblTitle = new Label(); lblTitle.Text = "板龙骨设置参数"; lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 10, System.Drawing.FontStyle.Bold); lblTitle.Location = new Point(column1, yPos); lblTitle.Size = new Size(200, 20); page.Controls.Add(lblTitle); yPos += 30; // 默认楼板厚和模板厚 Label lblDefaultSlab = new Label(); lblDefaultSlab.Text = "默认楼板厚:"; lblDefaultSlab.Location = new Point(column1, yPos); lblDefaultSlab.Size = new Size(90, 20); page.Controls.Add(lblDefaultSlab); txtDefaultSlabThickness = new TextBox(); txtDefaultSlabThickness.Text = "120"; txtDefaultSlabThickness.Location = new Point(column1 + 100, yPos); txtDefaultSlabThickness.Size = new Size(50, 20); page.Controls.Add(txtDefaultSlabThickness); Label lblFormwork = new Label(); lblFormwork.Text = "模板厚:"; lblFormwork.Location = new Point(column1 + 160, yPos); lblFormwork.Size = new Size(70, 20); page.Controls.Add(lblFormwork); txtFormworkThickness = new TextBox(); txtFormworkThickness.Text = "15"; txtFormworkThickness.Location = new Point(column1 + 230, yPos); txtFormworkThickness.Size = new Size(50, 20); page.Controls.Add(txtFormworkThickness); yPos += 40; // 绘制板底次龙骨 Label lblSlabSecondary = new Label(); lblSlabSecondary.Text = "绘制板底次龙骨:"; lblSlabSecondary.Location = new Point(column1, yPos); lblSlabSecondary.Size = new Size(labelWidth, 20); page.Controls.Add(lblSlabSecondary); radSlabSecondaryYes = new RadioButton(); radSlabSecondaryYes.Text = "是"; radSlabSecondaryYes.Checked = true; radSlabSecondaryYes.Location = new Point(column2, yPos); radSlabSecondaryYes.Size = new Size(40, 20); page.Controls.Add(radSlabSecondaryYes); radSlabSecondaryNo = new RadioButton(); radSlabSecondaryNo.Text = "否"; radSlabSecondaryNo.Location = new Point(column2 + 50, yPos); radSlabSecondaryNo.Size = new Size(40, 20); page.Controls.Add(radSlabSecondaryNo); // 绘制方向 Label lblDirection = new Label(); lblDirection.Text = "绘制方向:"; lblDirection.Location = new Point(column3, yPos); lblDirection.Size = new Size(70, 20); page.Controls.Add(lblDirection); radSlabSecondaryHorizontal = new RadioButton(); radSlabSecondaryHorizontal.Text = "横向"; radSlabSecondaryHorizontal.Location = new Point(column3 + 80, yPos); radSlabSecondaryHorizontal.Size = new Size(50, 20); page.Controls.Add(radSlabSecondaryHorizontal); radSlabSecondaryLongitudinal = new RadioButton(); radSlabSecondaryLongitudinal.Text = "纵向"; radSlabSecondaryLongitudinal.Location = new Point(column3 + 140, yPos); radSlabSecondaryLongitudinal.Size = new Size(50, 20); radSlabSecondaryLongitudinal.Checked = true; page.Controls.Add(radSlabSecondaryLongitudinal); // 材料 Label lblMaterial = new Label(); lblMaterial.Text = "材料:"; lblMaterial.Location = new Point(column4, yPos); lblMaterial.Size = new Size(50, 20); page.Controls.Add(lblMaterial); cmbSlabSecondaryMaterial = new ComboBox(); cmbSlabSecondaryMaterial.Items.AddRange(new object[] { "木方", "方钢", "钢管" }); cmbSlabSecondaryMaterial.SelectedIndex = 0; cmbSlabSecondaryMaterial.Location = new Point(column4 + 50, yPos); cmbSlabSecondaryMaterial.Size = new Size(80, 20); page.Controls.Add(cmbSlabSecondaryMaterial); yPos += 30; // 规格 Label lblSpec = new Label(); lblSpec.Text = "规格:"; lblSpec.Location = new Point(column2, yPos); lblSpec.Size = new Size(40, 20); page.Controls.Add(lblSpec); Label lblHeight = new Label(); lblHeight.Text = "高:"; lblHeight.Location = new Point(column2 + 50, yPos); lblHeight.Size = new Size(30, 20); page.Controls.Add(lblHeight); txtSlabSecondaryHeight = new TextBox(); txtSlabSecondaryHeight.Text = "90"; txtSlabSecondaryHeight.Location = new Point(column2 + 80, yPos); txtSlabSecondaryHeight.Size = new Size(50, 20); page.Controls.Add(txtSlabSecondaryHeight); Label lblWidth = new Label(); lblWidth.Text = "宽:"; lblWidth.Location = new Point(column2 + 140, yPos); lblWidth.Size = new Size(30, 20); page.Controls.Add(lblWidth); txtSlabSecondaryWidth = new TextBox(); txtSlabSecondaryWidth.Text = "40"; txtSlabSecondaryWidth.Location = new Point(column2 + 170, yPos); txtSlabSecondaryWidth.Size = new Size(50, 20); page.Controls.Add(txtSlabSecondaryWidth); Label lblSpacing = new Label(); lblSpacing.Text = "间距:"; lblSpacing.Location = new Point(column2 + 230, yPos); lblSpacing.Size = new Size(40, 20); page.Controls.Add(lblSpacing); txtSlabSecondarySpacing = new TextBox(); txtSlabSecondarySpacing.Text = "200"; txtSlabSecondarySpacing.Location = new Point(column2 + 270, yPos); txtSlabSecondarySpacing.Size = new Size(50, 20); page.Controls.Add(txtSlabSecondarySpacing); yPos += 40; // 绘制板底主龙骨 Label lblSlabPrimary = new Label(); lblSlabPrimary.Text = "绘制板底主龙骨:"; lblSlabPrimary.Location = new Point(column1, yPos); lblSlabPrimary.Size = new Size(labelWidth, 20); page.Controls.Add(lblSlabPrimary); radSlabPrimaryYes = new RadioButton(); radSlabPrimaryYes.Text = "是"; radSlabPrimaryYes.Checked = true; radSlabPrimaryYes.Location = new Point(column2, yPos); radSlabPrimaryYes.Size = new Size(40, 20); page.Controls.Add(radSlabPrimaryYes); radSlabPrimaryNo = new RadioButton(); radSlabPrimaryNo.Text = "否"; radSlabPrimaryNo.Location = new Point(column2 + 50, yPos); radSlabPrimaryNo.Size = new Size(40, 20); page.Controls.Add(radSlabPrimaryNo); // 材料 Label lblMaterial2 = new Label(); lblMaterial2.Text = "材料:"; lblMaterial2.Location = new Point(column3, yPos); lblMaterial2.Size = new Size(50, 20); page.Controls.Add(lblMaterial2); cmbSlabPrimaryMaterial = new ComboBox(); cmbSlabPrimaryMaterial.Items.AddRange(new object[] { "木方", "方钢", "钢管" }); cmbSlabPrimaryMaterial.SelectedIndex = 2; cmbSlabPrimaryMaterial.Location = new Point(column3 + 50, yPos); cmbSlabPrimaryMaterial.Size = new Size(80, 20); page.Controls.Add(cmbSlabPrimaryMaterial); yPos += 30; // 规格 Label lblSpec2 = new Label(); lblSpec2.Text = "规格:"; lblSpec2.Location = new Point(column2, yPos); lblSpec2.Size = new Size(40, 20); page.Controls.Add(lblSpec2); Label lblHeight2 = new Label(); lblHeight2.Text = "高:"; lblHeight2.Location = new Point(column2 + 50, yPos); lblHeight2.Size = new Size(30, 20); page.Controls.Add(lblHeight2); txtSlabPrimaryHeight = new TextBox(); txtSlabPrimaryHeight.Text = "100"; txtSlabPrimaryHeight.Location = new Point(column2 + 80, yPos); txtSlabPrimaryHeight.Size = new Size(50, 20); page.Controls.Add(txtSlabPrimaryHeight); Label lblWidth2 = new Label(); lblWidth2.Text = "宽:"; lblWidth2.Location = new Point(column2 + 140, yPos); lblWidth2.Size = new Size(30, 20); page.Controls.Add(lblWidth2); txtSlabPrimaryWidth = new TextBox(); txtSlabPrimaryWidth.Text = "100"; txtSlabPrimaryWidth.Location = new Point(column2 + 170, yPos); txtSlabPrimaryWidth.Size = new Size(50, 20); page.Controls.Add(txtSlabPrimaryWidth); } private void SetupEventHandlers() { // 设置事件处理器 radBeamSideSecondaryYes.CheckedChanged += (s, e) => { bool enabled = radBeamSideSecondaryYes.Checked; radBeamSideSecondaryHorizontal.Enabled = enabled; radBeamSideSecondaryVertical.Enabled = enabled; cmbBeamSideSecondaryMaterial.Enabled = enabled; txtBeamSideSecondaryHeight.Enabled = enabled; txtBeamSideSecondaryWidth.Enabled = enabled; txtBeamSideSecondarySpacing.Enabled = enabled; if (enabled) { UpdateBeamSideSecondaryControls(); } }; radBeamSideSecondaryNo.CheckedChanged += (s, e) => { bool enabled = !radBeamSideSecondaryNo.Checked; radBeamSideSecondaryHorizontal.Enabled = enabled; radBeamSideSecondaryVertical.Enabled = enabled; cmbBeamSideSecondaryMaterial.Enabled = enabled; txtBeamSideSecondaryHeight.Enabled = enabled; txtBeamSideSecondaryWidth.Enabled = enabled; txtBeamSideSecondarySpacing.Enabled = enabled; }; radBeamSideSecondaryHorizontal.CheckedChanged += (s, e) => UpdateBeamSideSecondaryControls(); radBeamSideSecondaryVertical.CheckedChanged += (s, e) => UpdateBeamSideSecondaryControls(); cmbBeamSideSecondaryMaterial.SelectedIndexChanged += (s, e) => UpdateBeamSideSecondaryControls(); // 其他事件处理器... } private void UpdateBeamSideSecondaryControls() { bool isEnabled = radBeamSideSecondaryYes.Checked; bool isHorizontal = radBeamSideSecondaryHorizontal.Checked; bool isVertical = radBeamSideSecondaryVertical.Checked; string material = cmbBeamSideSecondaryMaterial.Text; if (!isEnabled) { // 如果选择"否",禁用所有控件 radBeamSideSecondaryHorizontal.Enabled = false; radBeamSideSecondaryVertical.Enabled = false; cmbBeamSideSecondaryMaterial.Enabled = false; txtBeamSideSecondaryHeight.Enabled = false; txtBeamSideSecondaryWidth.Enabled = false; txtBeamSideSecondarySpacing.Enabled = false; return; } // 根据文档要求更新控件状态 if (isVertical) { txtBeamSideSecondaryHeight.Enabled = false; txtBeamSideSecondarySpacing.Enabled = false; txtBeamSideSecondaryWidth.Enabled = true; } else if (isHorizontal) { txtBeamSideSecondaryHeight.Enabled = true; txtBeamSideSecondarySpacing.Enabled = true; txtBeamSideSecondaryWidth.Enabled = true; } if (material == "钢管") { txtBeamSideSecondaryHeight.Enabled = false; txtBeamSideSecondaryWidth.Enabled = false; txtBeamSideSecondarySpacing.Enabled = false; } } protected override void OnFormClosing(FormClosingEventArgs e) { if (this.DialogResult == DialogResult.OK) { // 收集参数 Parameters.BeamSideSecondary.Enabled = radBeamSideSecondaryYes.Checked; Parameters.BeamSideSecondary.Direction = radBeamSideSecondaryHorizontal.Checked ? "Horizontal" : "Vertical"; Parameters.BeamSideSecondary.Material = cmbBeamSideSecondaryMaterial.Text; if (double.TryParse(txtBeamSideSecondaryHeight.Text, out double height)) Parameters.BeamSideSecondary.Height = height; if (double.TryParse(txtBeamSideSecondaryWidth.Text, out double width)) Parameters.BeamSideSecondary.Width = width; if (double.TryParse(txtBeamSideSecondarySpacing.Text, out double spacing)) Parameters.BeamSideSecondary.Spacing = spacing; // 收集其他参数... Parameters.DefaultSlabThickness = double.Parse(txtDefaultSlabThickness.Text); Parameters.FormworkThickness = double.Parse(txtFormworkThickness.Text); // 梁侧主龙骨参数 Parameters.BeamSidePrimary.Enabled = radBeamSidePrimaryYes.Checked; Parameters.BeamSidePrimary.Direction = radBeamSidePrimaryHorizontal.Checked ? "Horizontal" : "Vertical"; Parameters.BeamSidePrimary.Material = cmbBeamSidePrimaryMaterial.Text; if (double.TryParse(txtBeamSidePrimaryHeight.Text, out double primaryHeight)) Parameters.BeamSidePrimary.Height = primaryHeight; if (double.TryParse(txtBeamSidePrimaryWidth.Text, out double primaryWidth)) Parameters.BeamSidePrimary.Width = primaryWidth; if (double.TryParse(txtBeamSidePrimaryDiameter.Text, out double diameter)) Parameters.BeamSidePrimary.Diameter = diameter; // 梁对拉螺栓参数 if (double.TryParse(txtBeamBoltBottomOffset.Text, out double bottomOffset)) Parameters.BeamBolt.BottomOffset = bottomOffset; if (double.TryParse(txtBeamBoltTopOffset.Text, out double topOffset)) Parameters.BeamBolt.TopOffset = topOffset; if (double.TryParse(txtBeamBoltMaxSpacing.Text, out double maxSpacing)) Parameters.BeamBolt.MaxSpacing = maxSpacing; // 梁底次龙骨参数 Parameters.BeamBottomSecondary.Enabled = radBeamBottomSecondaryYes.Checked; Parameters.BeamBottomSecondary.Direction = radBeamBottomSecondaryLongitudinal.Checked ? "Longitudinal" : "Horizontal"; Parameters.BeamBottomSecondary.Material = cmbBeamBottomSecondaryMaterial.Text; if (double.TryParse(txtBeamBottomSecondaryHeight.Text, out double bottomSecondaryHeight)) Parameters.BeamBottomSecondary.Height = bottomSecondaryHeight; if (double.TryParse(txtBeamBottomSecondaryWidth.Text, out double bottomSecondaryWidth)) Parameters.BeamBottomSecondary.Width = bottomSecondaryWidth; if (double.TryParse(txtBeamBottomSecondarySpacing.Text, out double bottomSecondarySpacing)) Parameters.BeamBottomSecondary.Spacing = bottomSecondarySpacing; // 梁底主龙骨参数 Parameters.BeamBottomPrimary.Enabled = radBeamBottomPrimaryYes.Checked; Parameters.BeamBottomPrimary.Material = cmbBeamBottomPrimaryMaterial.Text; if (double.TryParse(txtBeamBottomPrimaryHeight.Text, out double bottomPrimaryHeight)) Parameters.BeamBottomPrimary.Height = bottomPrimaryHeight; if (double.TryParse(txtBeamBottomPrimaryWidth.Text, out double bottomPrimaryWidth)) Parameters.BeamBottomPrimary.Width = bottomPrimaryWidth; // 板底次龙骨参数 Parameters.Slab.SecondaryEnabled = radSlabSecondaryYes.Checked; Parameters.Slab.SecondaryDirection = radSlabSecondaryLongitudinal.Checked ? "Longitudinal" : "Horizontal"; Parameters.Slab.SecondaryMaterial = cmbSlabSecondaryMaterial.Text; if (double.TryParse(txtSlabSecondaryHeight.Text, out double slabSecondaryHeight)) Parameters.Slab.SecondaryHeight = slabSecondaryHeight; if (double.TryParse(txtSlabSecondaryWidth.Text, out double slabSecondaryWidth)) Parameters.Slab.SecondaryWidth = slabSecondaryWidth; if (double.TryParse(txtSlabSecondarySpacing.Text, out double slabSecondarySpacing)) Parameters.Slab.SecondarySpacing = slabSecondarySpacing; // 板底主龙骨参数 Parameters.Slab.PrimaryEnabled = radSlabPrimaryYes.Checked; Parameters.Slab.PrimaryMaterial = cmbSlabPrimaryMaterial.Text; if (double.TryParse(txtSlabPrimaryHeight.Text, out double slabPrimaryHeight)) Parameters.Slab.PrimaryHeight = slabPrimaryHeight; if (double.TryParse(txtSlabPrimaryWidth.Text, out double slabPrimaryWidth)) Parameters.Slab.PrimaryWidth = slabPrimaryWidth; } base.OnFormClosing(e); } } public class BeamSlabCommand { [CommandMethod("DB")] public void StartBeamSlab() { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; // 显示参数设置窗口 using (ParameterForm form = new ParameterForm()) { // 使用完全限定名解决Application歧义 if (Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(null, form, false) != DialogResult.OK) return; BeamSlabParameters parameters = form.Parameters; // 开始绘制循环 DrawBeamSlab(doc, ed, parameters); } } private void DrawBeamSlab(Document doc, Editor ed, BeamSlabParameters parameters) { Database db = doc.Database; List<Point3d> beamPoints = new List<Point3d>(); List<double> beamHeights = new List<double>(); List<double> slabThicknesses = new List<double>(); while (true) { // 1. 获取梁的第一点 PromptPointResult ppr1 = ed.GetPoint("\n请点击梁的第一点: "); if (ppr1.Status != PromptStatus.OK) break; // 2. 获取梁的第二点 PromptPointResult ppr2 = ed.GetPoint("\n请点击梁的第二点: "); if (ppr2.Status != PromptStatus.OK) break; // 3. 获取梁高 PromptDoubleOptions pdoHeight = new PromptDoubleOptions("\n请输入梁高(mm): "); pdoHeight.AllowNegative = false; pdoHeight.DefaultValue = 500; // 默认梁高500mm PromptDoubleResult pdrHeight = ed.GetDouble(pdoHeight); if (pdrHeight.Status != PromptStatus.OK) break; double beamHeight = pdrHeight.Value; // 4. 获取板厚或升降板信息 double slabThickness = GetSlabThickness(ed, parameters.DefaultSlabThickness); if (double.IsNaN(slabThickness)) break; beamPoints.Add(ppr1.Value); beamPoints.Add(ppr2.Value); beamHeights.Add(beamHeight); slabThicknesses.Add(slabThickness); // 绘制梁和板 using (Transaction tr = db.TransactionManager.StartTransaction()) { DrawBeamAndSlab(tr, db, ppr1.Value, ppr2.Value, beamHeight, slabThickness, parameters); tr.Commit(); } } // 完成绘制,闭合区域并填充 if (beamPoints.Count >= 4) { using (Transaction tr = db.TransactionManager.StartTransaction()) { CompleteDrawing(tr, db, beamPoints, beamHeights, slabThicknesses, parameters); tr.Commit(); } } } private double GetSlabThickness(Editor ed, double defaultThickness) { PromptKeywordOptions pko = new PromptKeywordOptions("\n请输入[板厚(A)/升降板(S)]: "); pko.Keywords.Add("A"); pko.Keywords.Add("S"); pko.Keywords.Default = "A"; PromptResult pr = ed.GetKeywords(pko); if (pr.Status != PromptStatus.OK) return double.NaN; if (pr.StringResult == "A") { PromptDoubleOptions pdo = new PromptDoubleOptions("\n输入板厚(mm): "); pdo.DefaultValue = defaultThickness; pdo.AllowNegative = false; PromptDoubleResult pdr = ed.GetDouble(pdo); if (pdr.Status != PromptStatus.OK) return double.NaN; return pdr.Value; } else // "S" { PromptDoubleOptions pdo = new PromptDoubleOptions("\n请输入升降板高度(升板为正数,降板为负数)mm: "); pdo.AllowNegative = true; PromptDoubleResult pdr = ed.GetDouble(pdo); if (pdr.Status != PromptStatus.OK) return double.NaN; return pdr.Value; } } private void DrawBeamAndSlab(Transaction tr, Database db, Point3d pt1, Point3d pt2, double beamHeight, double slabThickness, BeamSlabParameters parameters) { // 计算偏移量 double offset = beamHeight - slabThickness; // 绘制梁的双线 Vector3d direction = (pt2 - pt1).GetNormal(); Vector3d perpendicular = direction.GetPerpendicularVector(); double halfFormwork = parameters.FormworkThickness / 2; Point3d innerPt1 = pt1 + perpendicular * halfFormwork; Point3d innerPt2 = pt2 + perpendicular * halfFormwork; Point3d outerPt1 = pt1 - perpendicular * halfFormwork; Point3d outerPt2 = pt2 - perpendicular * halfFormwork; // 创建梁的双线 Polyline beamInner = CreatePolyline(new[] { innerPt1, innerPt2 }); Polyline beamOuter = CreatePolyline(new[] { outerPt1, outerPt2 }); // 添加到数据库 AddToModelSpace(tr, db, beamInner); AddToModelSpace(tr, db, beamOuter); // 绘制竖向梁线 Vector3d verticalOffset = new Vector3d(0, 0, -offset); Polyline vertical1 = CreatePolyline(new[] { innerPt1, innerPt1 + verticalOffset }); Polyline vertical2 = CreatePolyline(new[] { innerPt2, innerPt2 + verticalOffset }); AddToModelSpace(tr, db, vertical1); AddToModelSpace(tr, db, vertical2); // 绘制板底线 Point3d slabPt1 = innerPt1 + verticalOffset; Point3d slabPt2 = innerPt2 + verticalOffset; Polyline slabLine = CreatePolyline(new[] { slabPt1, slabPt2 }); AddToModelSpace(tr, db, slabLine); // 根据参数绘制龙骨和对拉螺栓 if (parameters.BeamSideSecondary.Enabled) DrawBeamSideSecondary(tr, db, innerPt1, innerPt2, verticalOffset, parameters.BeamSideSecondary); if (parameters.BeamSidePrimary.Enabled) DrawBeamSidePrimary(tr, db, innerPt1, innerPt2, verticalOffset, parameters.BeamSidePrimary); if (parameters.BeamBolt.Enabled) DrawBeamBolts(tr, db, innerPt1, innerPt2, verticalOffset, parameters.BeamBolt); } private void DrawBeamSideSecondary(Transaction tr, Database db, Point3d pt1, Point3d pt2, Vector3d verticalOffset, BeamSideSecondaryParameters parameters) { // 根据参数绘制梁侧次龙骨 if (parameters.Direction == "Horizontal") { // 水平布置 double spacing = parameters.Spacing; double distance = pt1.DistanceTo(pt2); int count = (int)(distance / spacing); for (int i = 0; i <= count; i++) { double ratio = (double)i / count; Point3d position = pt1 + (pt2 - pt1) * ratio; // 绘制矩形木方或方钢 DrawTimberOrSteel(tr, db, position, verticalOffset, parameters.Material, parameters.Height, parameters.Width); } } else { // 竖向布置 Point3d start = pt1 + (pt2 - pt1) / 2; // 中间位置 DrawVerticalTimberOrSteel(tr, db, start, verticalOffset, parameters.Material, parameters.Width); } } private void DrawBeamSidePrimary(Transaction tr, Database db, Point3d pt1, Point3d pt2, Vector3d verticalOffset, BeamSidePrimaryParameters parameters) { // 实现梁侧主龙骨绘制逻辑 // 根据参数绘制梁侧主龙骨 // 这里需要根据实际需求实现 } private void DrawBeamBolts(Transaction tr, Database db, Point3d pt1, Point3d pt2, Vector3d verticalOffset, BeamBoltParameters parameters) { // 实现对拉螺栓绘制逻辑 // 根据参数绘制对拉螺栓 // 这里需要根据实际需求实现 } private void DrawTimberOrSteel(Transaction tr, Database db, Point3d position, Vector3d verticalOffset, string material, double height, double width) { // 根据材料类型绘制木方或方钢 if (material == "木方") { // 绘制木方矩形并填充 Polyline timber = CreateRectangle(position, width, height); AddToModelSpace(tr, db, timber); // 填充木方图案 Hatch hatch = CreateHatch(timber, "AHSI36", 100); AddToModelSpace(tr, db, hatch); } else if (material == "方钢" || material == "钢管") { // 绘制方钢或钢管(双线) double thickness = material == "方钢" ? 3 : 1.5; // 方钢壁厚3mm,钢管壁厚1.5mm DrawHollowSection(tr, db, position, width, height, thickness); } } private void DrawVerticalTimberOrSteel(Transaction tr, Database db, Point3d position, Vector3d verticalOffset, string material, double width) { // 实现竖向木方或方钢绘制逻辑 // 这里需要根据实际需求实现 } private void DrawHollowSection(Transaction tr, Database db, Point3d position, double width, double height, double thickness) { // 实现空心截面绘制逻辑 // 这里需要根据实际需求实现 } private void CompleteDrawing(Transaction tr, Database db, List<Point3d> beamPoints, List<double> beamHeights, List<double> slabThicknesses, BeamSlabParameters parameters) { // 创建闭合多段线框 Polyline boundary = new Polyline(); // 添加所有点形成闭合区域 for (int i = 0; i < beamPoints.Count; i++) { Point3d point = beamPoints[i]; boundary.AddVertexAt(i, new Point2d(point.X, point.Y), 0, 0, 0); } boundary.Closed = true; AddToModelSpace(tr, db, boundary); // 填充区域 Hatch hatch = CreateHatch(boundary, "AR-SAND", 100); AddToModelSpace(tr, db, hatch); } private Polyline CreatePolyline(Point3d[] points) { Polyline pl = new Polyline(); for (int i = 0; i < points.Length; i++) { pl.AddVertexAt(i, new Point2d(points[i].X, points[i].Y), 0, 0, 0); } return pl; } private Polyline CreateRectangle(Point3d center, double width, double height) { double halfWidth = width / 2; double halfHeight = height / 2; Polyline rect = new Polyline(); rect.AddVertexAt(0, new Point2d(center.X - halfWidth, center.Y - halfHeight), 0, 0, 0); rect.AddVertexAt(1, new Point2d(center.X + halfWidth, center.Y - halfHeight), 0, 0, 0); rect.AddVertexAt(2, new Point2d(center.X + halfWidth, center.Y + halfHeight), 0, 0, 0); rect.AddVertexAt(3, new Point2d(center.X - halfWidth, center.Y + halfHeight), 0, 0, 0); rect.Closed = true; return rect; } private Hatch CreateHatch(Polyline boundary, string patternName, double scale) { Hatch hatch = new Hatch(); hatch.SetHatchPattern(HatchPatternType.PreDefined, patternName); hatch.PatternScale = scale; hatch.Associative = true; ObjectIdCollection boundaries = new ObjectIdCollection(); boundaries.Add(boundary.ObjectId); hatch.AppendLoop(HatchLoopTypes.Outermost, boundaries); return hatch; } private void AddToModelSpace(Transaction tr, Database db, Entity entity) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); btr.AppendEntity(entity); tr.AddNewlyCreatedDBObject(entity, true); } } } 参数设置窗口界面显示不完整比例失衡
08-21
import tkinter as tk from tkinter import ttk import random import datetime import calendar class SalesChartApp: def __init__(self, root): self.root = root self.root.title("年度销售额统计") self.root.geometry("900x600") # 初始化数据存储 self.current_year = datetime.datetime.now().year self.sales_data = {year: [0] * 12 for year in range(self.current_year - 2, self.current_year + 1)} # 创建控制面板 control_frame = ttk.Frame(root, padding=10) control_frame.pack(fill=tk.X) # 年份选择 ttk.Label(control_frame, text="选择年份:").grid(row=0, column=0, padx=5) self.year_var = tk.IntVar(value=self.current_year) years = list(range(self.current_year - 2, self.current_year + 1)) self.year_combo = ttk.Combobox( control_frame, textvariable=self.year_var, values=years, state="readonly", width=8 ) self.year_combo.grid(row=0, column=1, padx=5) self.year_combo.bind("<<ComboboxSelected>>", self.update_chart) # 自动更新按钮 self.auto_update_var = tk.BooleanVar(value=True) auto_update_btn = ttk.Checkbutton( control_frame, text="自动年度更新", variable=self.auto_update_var ) auto_update_btn.grid(row=0, column=2, padx=20) # 添加模拟数据按钮 ttk.Button( control_frame, text="生成模拟数据", command=self.generate_data ).grid(row=0, column=3, padx=5) # 创建图表画布 self.chart_canvas = tk.Canvas(root, bg="white", height=500) self.chart_canvas.pack(fill=tk.BOTH, expand=True, padx=20, pady=10) # 初始化数据并绘制图表 self.generate_data() self.update_chart() # 设置年度自动更新 self.schedule_annual_update() def generate_data(self): """生成模拟销售数据""" for year in self.sales_data: self.sales_data[year] = [random.randint(8000, 20000) for _ in range(12)] def update_chart(self, event=None): """更新图表显示""" selected_year = self.year_var.get() self.draw_bar_chart(selected_year) def draw_bar_chart(self, year): """在画布上绘制条形图""" self.chart_canvas.delete("all") data = self.sales_data[year] # 获取画布尺寸 canvas_width = self.chart_canvas.winfo_width() canvas_height = self.chart_canvas.winfo_height() if canvas_width <= 1 or canvas_height <= 1: return # 防止初始化时尺寸错误 # 图表参数 margin = 60 chart_width = canvas_width - 2 * margin chart_height = canvas_height - 2 * margin bar_width = chart_width / 15 gap = bar_width / 2 # 计算最大值用于缩放 max_value = max(data) * 1.1 # 绘制坐标轴 self.chart_canvas.create_line(margin, margin, margin, canvas_height - margin, width=2) # Y轴 self.chart_canvas.create_line(margin, canvas_height - margin, canvas_width - margin, canvas_height - margin, width=2) # X轴 # 绘制标题 title = f"{year}年各月销售额统计(单位:元)" self.chart_canvas.create_text(canvas_width/2, 20, text=title, font=("Arial", 14, "bold")) # 绘制Y轴刻度和标签 for i in range(6): y = canvas_height - margin - (i * chart_height / 5) value = int(max_value * i / 5) self.chart_canvas.create_line(margin - 5, y, margin, y, width=1) self.chart_canvas.create_text(margin - 10, y, text=f"{value:,}", anchor=tk.E, font=("Arial", 9)) # 绘制条形和标签 for i, month in enumerate(calendar.month_abbr[1:]): # 跳过空值 # 计算条形位置 x1 = margin + gap + i * (bar_width + gap) x2 = x1 + bar_width y1 = canvas_height - margin y2 = canvas_height - margin - (data[i] / max_value) * chart_height # 绘制条形 bar_color = "#4e79a7" # 蓝色 self.chart_canvas.create_rectangle(x1, y1, x2, y2, fill=bar_color, outline="black") # 显示月份 self.chart_canvas.create_text( (x1 + x2) / 2, canvas_height - margin + 15, text=month, font=("Arial", 10) ) # 显示销售额数值 self.chart_canvas.create_text( (x1 + x2) / 2, y2 - 15, text=f"{data[i]:,}", font=("Arial", 9), fill="white" ) # 添加悬停效果 tag_name = f"bar_{i}" self.chart_canvas.create_rectangle( x1, y1, x2, y2, fill="", outline="", tags=(tag_name,) ) self.chart_canvas.tag_bind( tag_name, "<Enter>", lambda e, val=data[i], month=month: self.show_tooltip(e, val, month) ) self.chart_canvas.tag_bind(tag_name, "<Leave>", self.hide_tooltip) def show_tooltip(self, event, value, month): """显示悬停提示""" self.tooltip = tk.Toplevel(self.root) self.tooltip.wm_overrideredirect(True) self.tooltip.wm_geometry(f"+{event.x_root+10}+{event.y_root+10}") label = tk.Label( self.tooltip, text=f"{month}: ¥{value:,}", bg="lightyellow", relief="solid", borderwidth=1 ) label.pack() def hide_tooltip(self, event): """隐藏悬停提示""" if hasattr(self, 'tooltip') and self.tooltip: self.tooltip.destroy() def schedule_annual_update(self): """安排年度自动更新任务""" now = datetime.datetime.now() # 计算到明年1月1日的时间(毫秒) next_year = now.year + 1 next_january = datetime.datetime(next_year, 1, 1) delay_ms = int((next_january - now).total_seconds() * 1000) # 安排更新任务 self.root.after(delay_ms, self.annual_update) def annual_update(self): """年度自动更新""" if self.auto_update_var.get(): # 更新年份范围 self.current_year += 1 new_years = list(range(self.current_year - 2, self.current_year + 1)) # 添加新一年的数据 self.sales_data[self.current_year] = [random.randint(8000, 20000) for _ in range(12)] # 移除旧数据(保留最近3年) for year in list(self.sales_data.keys()): if year < self.current_year - 2: del self.sales_data[year] # 更新下拉框 self.year_combo['values'] = new_years self.year_var.set(self.current_year) # 更新图表 self.update_chart() # 重新安排下一次更新 self.schedule_annual_update() if __name__ == "__main__": root = tk.Tk() app = SalesChartApp(root) root.mainloop() 加上填写数据
07-30
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值