From 2a4894657f5b2583b2b2598ea9ac44273a579443 Mon Sep 17 00:00:00 2001 From: sladro Date: Wed, 31 Dec 2025 15:45:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=BACAD=E6=8F=92=E4=BB=B6=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=9B=BE=E7=BA=B8=E5=8F=82=E6=95=B0=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E5=92=8C=E8=A1=A8=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UI/DrawingParamsForm.cs | 43 ++++++++--- UI/ParamDrawingPanel.cs | 164 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 192 insertions(+), 15 deletions(-) diff --git a/UI/DrawingParamsForm.cs b/UI/DrawingParamsForm.cs index 8035110..ba9e5ad 100644 --- a/UI/DrawingParamsForm.cs +++ b/UI/DrawingParamsForm.cs @@ -33,12 +33,14 @@ namespace CadParamPluging.UI private const string KeyMinWallThickness = "MinWallThickness"; public ParamBag Result { get; private set; } + private ParamBag _loadedDefaults; // 新增:外部传入的默认值 - public DrawingParamsForm(ParamCatalog catalog, TemplateSchemaDefinition schema) + public DrawingParamsForm(ParamCatalog catalog, TemplateSchemaDefinition schema, ParamBag loadedDefaults = null) { _catalog = (catalog ?? ParamCatalog.CreateDefault()).Clone(); _catalog.Normalize(); _schema = schema; + _loadedDefaults = loadedDefaults; // 存储传入的默认值 Text = "填写参数"; Size = new Size(980, 680); @@ -640,18 +642,32 @@ namespace CadParamPluging.UI private Control CreateControl(ParamDefinition def) { + var initialValue = def.DefaultValue; + + // 优先使用传入的默认值 (loadedDefaults) + if (_loadedDefaults != null) + { + var val = _loadedDefaults.GetString(def.Key); + if (val != null) // only if key exists + { + initialValue = val; + } + } + // 确保不为 null + if (initialValue == null) initialValue = string.Empty; + switch (def.Type) { case ParamValueType.Bool: - return new CheckBox { Checked = ParseBool(def.DefaultValue), AutoSize = true }; + return new CheckBox { Checked = ParseBool(initialValue), AutoSize = true }; case ParamValueType.Enum: - return CreateEnumCombo(def); + return CreateEnumCombo(def, initialValue); case ParamValueType.Int: - return CreateNumber(def, isInt: true); + return CreateNumber(def, isInt: true, overrideValue: initialValue); case ParamValueType.Double: - return CreateNumber(def, isInt: false); + return CreateNumber(def, isInt: false, overrideValue: initialValue); default: - return new TextBox { Text = def.DefaultValue ?? string.Empty }; + return new TextBox { Text = initialValue }; } } @@ -669,7 +685,7 @@ namespace CadParamPluging.UI || string.Equals(s.Trim(), "是", StringComparison.OrdinalIgnoreCase); } - private ComboBox CreateEnumCombo(ParamDefinition def) + private ComboBox CreateEnumCombo(ParamDefinition def, string initialValue) { // Allow manual edit to match many "下拉列表...可手动编辑" cases. var cb = new ComboBox { DropDownStyle = ComboBoxStyle.DropDown }; @@ -677,17 +693,17 @@ namespace CadParamPluging.UI if (arr.Length > 0) { cb.Items.AddRange(arr); - var idx = Array.FindIndex(arr, x => string.Equals(x, def.DefaultValue, StringComparison.OrdinalIgnoreCase)); + var idx = Array.FindIndex(arr, x => string.Equals(x, initialValue, StringComparison.OrdinalIgnoreCase)); cb.SelectedIndex = idx >= 0 ? idx : 0; } - if (!string.IsNullOrWhiteSpace(def.DefaultValue)) + if (!string.IsNullOrWhiteSpace(initialValue)) { - cb.Text = def.DefaultValue; + cb.Text = initialValue; } return cb; } - private Control CreateNumber(ParamDefinition def, bool isInt) + private Control CreateNumber(ParamDefinition def, bool isInt, string overrideValue) { var num = new NumericUpDown { @@ -705,7 +721,10 @@ namespace CadParamPluging.UI { num.Maximum = max; } - if (TryParseDecimal(def.DefaultValue, out var dv)) + + // 使用 overrideValue 或 def.DefaultValue + // 但 CreateNumber 被调用时,overrideValue 已经是处理过的“最终初始值” + if (TryParseDecimal(overrideValue, out var dv)) { if (dv < num.Minimum) dv = num.Minimum; if (dv > num.Maximum) dv = num.Maximum; diff --git a/UI/ParamDrawingPanel.cs b/UI/ParamDrawingPanel.cs index a6466bf..a1e73c7 100644 --- a/UI/ParamDrawingPanel.cs +++ b/UI/ParamDrawingPanel.cs @@ -187,6 +187,11 @@ namespace CadParamPluging.UI panel.Controls.Add(btnGenerate); panel.Controls.Add(btnSaveAs); + + var btnLoadParams = new Button { Text = "读取参数", AutoSize = true }; + btnLoadParams.Click += (_, __) => OnLoadParams(); + panel.Controls.Add(btnLoadParams); + panel.Controls.Add(btnSettings); // panel.Controls.Add(btnTestDraw); // 暂时屏蔽测试绘制按钮 return panel; @@ -786,10 +791,19 @@ namespace CadParamPluging.UI try { var bagToSave = bag; - // 注意:bag 已经在上面被使用了,直接传递即可。 - // 如果需要保存更完整的信息(比如模板路径),也可以添加到 bag 中 - // bagToSave.Set("_TemplatePath", _selectedTemplate.FilePath); + // 保存模板信息以便后续“读取参数”功能可以自动填充UI + if (_selectedTemplate != null) + { + bagToSave.Set("_TemplatePath", _selectedTemplate.FilePath); + bagToSave.Set("_LayoutName", _selectedTemplate.LayoutName); + } + // 保存面板选项 + bagToSave.Set("ProjectType", tplParams.ProjectType); + bagToSave.Set("DrawingType", tplParams.DrawingType); + bagToSave.Set("SheetSize", tplParams.SheetSize); + bagToSave.Set("SpecialCondition", tplParams.Scale); // tplParams.Scale 对应 _cbScale (特殊条件) + DictionaryHelper.SaveParams(doc.Database, bagToSave); AppendLog("参数已保存到图纸内部数据中。"); } @@ -866,6 +880,150 @@ namespace CadParamPluging.UI } } + private void OnLoadParams() + { + try + { + var doc = AcadApp.DocumentManager.MdiActiveDocument; + if (doc == null) + { + AppendLog("未找到活动图纸,无法读取参数。"); + return; + } + + ParamBag bag; + using (doc.LockDocument()) + { + bag = DictionaryHelper.ReadParams(doc.Database); + } + + if (bag == null || bag.Items == null || bag.Items.Count == 0) + { + AppendLog("当前图纸未找到存储的参数(或非本插件生成)。"); + return; + } + + // 1. 尝试根据 path 恢复模板选择 + var tplPath = bag.GetString("_TemplatePath"); + if (!string.IsNullOrWhiteSpace(tplPath)) + { + // 在 _cbTemplateList 中查找 + int foundIndex = -1; + for (int i = 0; i < _cbTemplateList.Items.Count; i++) + { + var item = _cbTemplateList.Items[i] as TemplateSelectionItem; + if (item != null && string.Equals(item.Info.FilePath, tplPath, StringComparison.OrdinalIgnoreCase)) + { + // 如果原来的选择也是布局,尝试匹配布局名 + var originalLayout = bag.GetString("_LayoutName"); + if (!string.IsNullOrWhiteSpace(originalLayout)) + { + if (string.Equals(item.Info.LayoutName, originalLayout, StringComparison.OrdinalIgnoreCase)) + { + foundIndex = i; + break; + } + } + else + { + // 只有 Model Space 情况,或者不精确匹配布局 + foundIndex = i; + break; + } + } + } + + if (foundIndex >= 0) + { + _cbTemplateList.SelectedIndex = foundIndex; + AppendLog($"已自动选中模板: {_cbTemplateList.Items[foundIndex]}"); + } + else + { + AppendLog($"注意: 未在列表中找到原模板文件: {Path.GetFileName(tplPath)},可能文件已移动或未加载路径。"); + } + } + + // 2. 恢复下拉框选项 + // ProjectType + TrySelectRequest(bag, "ProjectType", _cbProjectType); + // DrawingType + TrySelectRequest(bag, "DrawingType", _cbDrawingType); + // SheetSize + TrySelectRequest(bag, "SheetSize", _cbSheetSize); + // Scale (DrawingScale) - 注意我们下拉框叫 _cbScale,参数里可能是 DrawingScale + var scaleVal = bag.GetString("DrawingScale"); + // 特殊条件/Scale 其实是一个 ComboBox,通常用于 SpecialConditions + // 但 DrawingScale 是在生成时 Parse 出来的。 + // 这里的 _cbScale 绑定的是 options.SpecialConditions (e.g. "中心冲孔") 还是 "1:50"? + // 回看代码 reset _cbScale 绑定的是 options.SpecialConditions (ResetComboBoxItems(_cbScale, options.SpecialConditions)) + // 而 "scale" 是指比例。 + // 观察 GenerateDrawing 逻辑: + // var tplParams = CollectTemplateParams(); -> Scale = _cbScale.Text + // 这个 _cbScale 存的是“特殊条件”。 + // 真正的比例是在 Bag.GetString("DrawingScale"),这是在 DrawParamsForm 里填写的。 + // + // 等等!看 Readme 和 UI 逻辑,主面板只有 4 个下拉框: Project/Drawing/SheetSize/Scale + // 其中 _cbScale 有时候被用作 Scale,但 DropdownOptions 绑定的是 SpecialConditions? + // Let's check ReloadDropdownOptions: + // ResetComboBoxItems(_cbScale, options.SpecialConditions); -> 所以 _cbScale 是“特殊条件”! + // 那比例去哪了? + // Readme 说 "ComboBox / TextBox:比例(Scale)" + // 让我们确认 CollectTemplateParams: Scale = _cbScale.Text (specialCondition) + // 看来目前主面板并没有“比例”输入框?比例是在 Form 里填写的? + // 检查 OnGenerateDrawing -> new DrawingParamsForm(catalog, schema) -> 这个 Form 里填写的具体参数。 + // + // 所以,OnLoadParams 只能恢复 面板上的 4 个下拉框。 + // 而 Form 里的参数(如 OuterDiameter, DrawingScale)需要在点“生成”后,弹出 Form 时自动填入。 + // 这需要修改 DrawingParamsForm 的构造函数或者逻辑,让它支持“默认值”从 Bag 中覆盖。 + + TrySelectRequest(bag, "SpecialCondition", _cbScale); // 假设存的时候 key 是 SpecialCondition? + // CollectTemplateParams 里没有把 template params 放入 bag。 + // 但是!DomainFacade.ValidateParameters 可能会用到。 + // 关键点:TemplateParams 只是用来匹配 TemplateKey。 + // 实际生成图纸时,OnGenerateDrawing 收集了 tplParams,然后 Build TemplateKey,然后 Load Schema,然后... + // 用 Form 填写了 Bag。 + // 所以“项目类型/图纸类型”等并没有被存入 Bag (除非 Form 里也有对应字段)。 + // 这是一个问题:Bag 主要是 Form 的结果。面板上的选择决定了 TemplateKey。 + // 我们在 SaveParamsToExtensionDictionary 时,只存了 Bag。 + // 如果面板上的选项(项目类型等)没在 Bag 里,我们就无法恢复面板状态! + // + // 补救措施:必须在 SaveParams 时把 tplParams 的内容也塞进 Bag。 + // 我刚刚加了 _TemplatePath/_LayoutName,但漏了 ProjectType 等。 + // + // 既然现在代码还没运行,我可以再加几个 Set。 + + AppendLog("参数读取完成。请点击【生成图纸】继续修改详细参数。"); + + // 将读取到的 Bag 暂存,以便 DrawingParamsForm 打开时使用它作为默认值 + _lastLoadedBag = bag; + } + catch (Exception ex) + { + AppendLog($"读取参数失败: {ex.Message}"); + Logger.Error("LoadParams", ex); + } + } + + private ParamBag _lastLoadedBag; // 暂存读取到的参数 + + private void TrySelectRequest(ParamBag bag, string key, ComboBox cb) + { + var val = bag.GetString(key); + if (!string.IsNullOrEmpty(val)) + { + // 尝试选中 + int idx = cb.FindStringExact(val); + if (idx >= 0) + { + cb.SelectedIndex = idx; + return; + } + // 如果没有,可能手动 Text? ComboBoxStyle.DropDownList 不允许。 + // 如果是 DropDownList 且不在列表中,就无法选中。 + } + } + private void ReloadDropdownOptions(DropdownOptions options) { if (options == null)