配置了全部参数
This commit is contained in:
parent
d4a9f092ff
commit
0a4a003a11
@ -60,6 +60,15 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="PluginEntry.cs" />
|
<Compile Include="PluginEntry.cs" />
|
||||||
<Compile Include="Common\BusinessException.cs" />
|
<Compile Include="Common\BusinessException.cs" />
|
||||||
|
<Compile Include="Common\ParamBag.cs" />
|
||||||
|
<Compile Include="Common\ParamCatalog.cs" />
|
||||||
|
<Compile Include="Common\ParamCatalogStore.cs" />
|
||||||
|
<Compile Include="Common\ParamDefinition.cs" />
|
||||||
|
<Compile Include="Common\ParamValueType.cs" />
|
||||||
|
<Compile Include="Common\TemplateKeyBuilder.cs" />
|
||||||
|
<Compile Include="Common\TemplateSchemaDefinition.cs" />
|
||||||
|
<Compile Include="Common\TemplateSchemas.cs" />
|
||||||
|
<Compile Include="Common\TemplateSchemaStore.cs" />
|
||||||
<Compile Include="Common\DropdownOptions.cs" />
|
<Compile Include="Common\DropdownOptions.cs" />
|
||||||
<Compile Include="Common\DropdownOptionsStore.cs" />
|
<Compile Include="Common\DropdownOptionsStore.cs" />
|
||||||
<Compile Include="Common\Logger.cs" />
|
<Compile Include="Common\Logger.cs" />
|
||||||
@ -79,15 +88,27 @@
|
|||||||
<Compile Include="UI\ParamDrawingPanel.cs">
|
<Compile Include="UI\ParamDrawingPanel.cs">
|
||||||
<SubType>UserControl</SubType>
|
<SubType>UserControl</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="UI\DrawingParamsForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="UI\LayoutSelectForm.cs">
|
<Compile Include="UI\LayoutSelectForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="UI\ModelSheetSelectForm.cs">
|
<Compile Include="UI\ModelSheetSelectForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="UI\ParamCatalogForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="UI\ParamDefinitionForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="UI\SettingsForm.cs">
|
<Compile Include="UI\SettingsForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="UI\TemplateSchemaBindingForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="UI\TextInputForm.cs">
|
<Compile Include="UI\TextInputForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
126
Common/ParamBag.cs
Normal file
126
Common/ParamBag.cs
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace CadParamPluging.Common
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class ParamBag
|
||||||
|
{
|
||||||
|
public List<ParamValue> Items { get; set; }
|
||||||
|
|
||||||
|
public ParamBag()
|
||||||
|
{
|
||||||
|
Items = new List<ParamValue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set(string key, string value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(key))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Items == null)
|
||||||
|
{
|
||||||
|
Items = new List<ParamValue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var existing = Items.FirstOrDefault(x => string.Equals(x.Key, key, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (existing == null)
|
||||||
|
{
|
||||||
|
Items.Add(new ParamValue { Key = key.Trim(), Value = value });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
existing.Value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetString(string key)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(key) || Items == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Items.FirstOrDefault(x => string.Equals(x.Key, key.Trim(), StringComparison.OrdinalIgnoreCase))?.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double GetDouble(string key, double fallback = 0)
|
||||||
|
{
|
||||||
|
var s = GetString(key);
|
||||||
|
if (string.IsNullOrWhiteSpace(s))
|
||||||
|
{
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var v))
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (double.TryParse(s, NumberStyles.Float, CultureInfo.CurrentCulture, out v))
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetInt(string key, int fallback = 0)
|
||||||
|
{
|
||||||
|
var s = GetString(key);
|
||||||
|
if (string.IsNullOrWhiteSpace(s))
|
||||||
|
{
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out var v))
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int.TryParse(s, NumberStyles.Integer, CultureInfo.CurrentCulture, out v))
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetBool(string key, bool fallback = false)
|
||||||
|
{
|
||||||
|
var s = GetString(key);
|
||||||
|
if (string.IsNullOrWhiteSpace(s))
|
||||||
|
{
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bool.TryParse(s, out var v))
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Equals(s, "1", StringComparison.OrdinalIgnoreCase) || string.Equals(s, "是", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Equals(s, "0", StringComparison.OrdinalIgnoreCase) || string.Equals(s, "否", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class ParamValue
|
||||||
|
{
|
||||||
|
public string Key { get; set; }
|
||||||
|
public string Value { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
644
Common/ParamCatalog.cs
Normal file
644
Common/ParamCatalog.cs
Normal file
@ -0,0 +1,644 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace CadParamPluging.Common
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class ParamCatalog
|
||||||
|
{
|
||||||
|
public List<ParamDefinition> Items { get; set; }
|
||||||
|
|
||||||
|
public ParamCatalog()
|
||||||
|
{
|
||||||
|
Items = new List<ParamDefinition>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParamCatalog Clone()
|
||||||
|
{
|
||||||
|
return new ParamCatalog
|
||||||
|
{
|
||||||
|
Items = (Items ?? new List<ParamDefinition>()).Select(x => x?.Clone()).Where(x => x != null).ToList()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Normalize()
|
||||||
|
{
|
||||||
|
if (Items == null)
|
||||||
|
{
|
||||||
|
Items = new List<ParamDefinition>();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var it in Items)
|
||||||
|
{
|
||||||
|
it?.Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
Items = Items
|
||||||
|
.Where(x => x != null && !string.IsNullOrWhiteSpace(x.Key))
|
||||||
|
.GroupBy(x => x.Key, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.Select(g => g.First())
|
||||||
|
.OrderBy(x => x.Order)
|
||||||
|
.ThenBy(x => x.Key, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParamDefinition FindByKey(string key)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(key) || Items == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Items.FirstOrDefault(x => string.Equals(x.Key, key.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ParamCatalog CreateDefault()
|
||||||
|
{
|
||||||
|
return new ParamCatalog
|
||||||
|
{
|
||||||
|
Items = new List<ParamDefinition>
|
||||||
|
{
|
||||||
|
// --- Material / classification ---
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "MaterialGrade",
|
||||||
|
Label = "材料牌号",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "数据库下拉列表(支持数据扩充),点选映射",
|
||||||
|
Order = 100,
|
||||||
|
Group = "材料"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "FeatureCategory",
|
||||||
|
Label = "特性分类",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "一般件",
|
||||||
|
EnumOptions = new List<string> { "一般件", "关键件", "重要件" },
|
||||||
|
Hint = "下拉列表(一般件/关键件/重要件),点选;关键件/重要件需加方框标注",
|
||||||
|
Order = 110,
|
||||||
|
Group = "材料"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "MaterialTechnicalCondition",
|
||||||
|
Label = "材料技术条件",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "多选下拉列表(支持数据扩充),选项用\"或\"连接",
|
||||||
|
Order = 120,
|
||||||
|
Group = "材料"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "ForgingTechnicalCondition",
|
||||||
|
Label = "锻件技术条件",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "多选下拉列表(支持数据扩充),选项用\"或\"连接",
|
||||||
|
Order = 130,
|
||||||
|
Group = "材料"
|
||||||
|
},
|
||||||
|
|
||||||
|
// --- Inspection / heat treatment ---
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "InspectionCategory",
|
||||||
|
Label = "检验类别",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "Ⅱ",
|
||||||
|
EnumOptions = new List<string> { "Ⅱ", "Ⅱa", "Ⅱ大", "Ⅲ", "Ⅳ" },
|
||||||
|
Hint = "单选下拉列表",
|
||||||
|
Order = 200,
|
||||||
|
Group = "检验/热处理"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "ForgingCategory",
|
||||||
|
Label = "锻件类别",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "Ⅱ",
|
||||||
|
EnumOptions = new List<string> { "Ⅱ", "Ⅲ", "Ⅳ" },
|
||||||
|
Hint = "单选下拉列表",
|
||||||
|
Order = 210,
|
||||||
|
Group = "检验/热处理"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "HeatTreatmentState",
|
||||||
|
Label = "热处理状态",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "预备热处理",
|
||||||
|
EnumOptions = new List<string> { "预备热处理", "热处理" },
|
||||||
|
Hint = "单选下拉列表",
|
||||||
|
Order = 220,
|
||||||
|
Group = "检验/热处理"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "HeatTreatmentProcess",
|
||||||
|
Label = "热处理制度",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "数据库下拉列表(支持数据扩充),点选",
|
||||||
|
Order = 230,
|
||||||
|
Group = "检验/热处理"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "Hardness",
|
||||||
|
Label = "硬度",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "组合选择:硬度符号+连接符+数值,可空",
|
||||||
|
Order = 240,
|
||||||
|
Group = "检验/热处理"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "UltrasonicRequirement",
|
||||||
|
Label = "超声波要求",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "手动输入,可空",
|
||||||
|
Order = 250,
|
||||||
|
Group = "检验/热处理"
|
||||||
|
},
|
||||||
|
|
||||||
|
// --- Marking / notes ---
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "MarkingContent",
|
||||||
|
Label = "标刻内容",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "多选下拉列表:零件尾号/零件号、材料牌号、熔炼炉号、锭节号、热处理炉次号、热处理炉批号、批次号",
|
||||||
|
Order = 300,
|
||||||
|
Group = "标注/说明"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "PartsPerForging",
|
||||||
|
Label = "一锻件可做零件数",
|
||||||
|
Type = ParamValueType.Int,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "1",
|
||||||
|
Hint = "手动编辑,默认为\"1\"",
|
||||||
|
Order = 310,
|
||||||
|
Group = "标注/说明"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "SurfaceRoughness",
|
||||||
|
Label = "表面粗糙度",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "空",
|
||||||
|
EnumOptions = new List<string> { "空", "0.8", "1.6", "3.2" },
|
||||||
|
Hint = "单选下拉列表,默认为空",
|
||||||
|
Order = 320,
|
||||||
|
Group = "标注/说明"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "DesignRevision",
|
||||||
|
Label = "设计图版次",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "空",
|
||||||
|
EnumOptions = new List<string> { "空", "A", "B", "C", "D", "E", "F" },
|
||||||
|
Hint = "下拉列表(A-F),可手动编辑,支持空选项",
|
||||||
|
Order = 330,
|
||||||
|
Group = "标注/说明"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "SerialInfo",
|
||||||
|
Label = "联号信息",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表模板\"X个A零件和X个B零件或X个C零件\",点选后可编辑",
|
||||||
|
Order = 340,
|
||||||
|
Group = "标注/说明"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "MachiningSpecimenRequirement",
|
||||||
|
Label = "机加试件需求",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表模板\"每批/每*件多投*件\",点选后可编辑",
|
||||||
|
Order = 350,
|
||||||
|
Group = "标注/说明"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "AdditionalNotes",
|
||||||
|
Label = "辅助说明",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "多选下拉列表:传递抗拉强度实测值、机加夹头标注、使用温度300℃以上、每批投产数量限制,点选后可编辑",
|
||||||
|
Order = 360,
|
||||||
|
Group = "标注/说明"
|
||||||
|
},
|
||||||
|
|
||||||
|
// --- Template key fields (also exist in panel dropdowns) ---
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "DeliveryStatus",
|
||||||
|
Label = "交付状态",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "毛料态",
|
||||||
|
EnumOptions = new List<string> { "毛料态", "车加工态" },
|
||||||
|
Hint = "单选下拉列表,决定后续模板",
|
||||||
|
Order = 400,
|
||||||
|
Group = "模板参数"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "ProcessMethod",
|
||||||
|
Label = "工艺方法",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "自由锻",
|
||||||
|
EnumOptions = new List<string> { "自由锻", "轧制" },
|
||||||
|
Hint = "单选下拉列表,决定后续模板",
|
||||||
|
Order = 410,
|
||||||
|
Group = "模板参数"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "StructuralFeature",
|
||||||
|
Label = "结构特征",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "方体",
|
||||||
|
EnumOptions = new List<string> { "方体", "饼盘", "轴杆", "环形" },
|
||||||
|
Hint = "单选下拉列表,决定后续模板",
|
||||||
|
Order = 420,
|
||||||
|
Group = "模板参数"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "SpecialCondition",
|
||||||
|
Label = "特殊条件",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "非中心冲孔",
|
||||||
|
EnumOptions = new List<string> { "非中心冲孔", "中心冲孔", "无圆头", "有圆头", "圆轴", "方轴" },
|
||||||
|
Hint = "单选下拉列表,决定后续模板",
|
||||||
|
Order = 430,
|
||||||
|
Group = "模板参数"
|
||||||
|
},
|
||||||
|
|
||||||
|
// --- Dimensions: ring (outer/inner/height) ---
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "OuterDiameter1",
|
||||||
|
Label = "外径Φ1",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "手动编辑",
|
||||||
|
Order = 500,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "OuterDiameter1TolPlus",
|
||||||
|
Label = "外径上差a1",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "0.5",
|
||||||
|
Hint = "车加工态:手动编辑(默认+0.5);毛料态:下拉列表(+2~+7)",
|
||||||
|
Order = 510,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "OuterDiameter1TolMinus",
|
||||||
|
Label = "外径下差b1",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "-0.5",
|
||||||
|
Hint = "车加工态:手动编辑(默认-0.5);毛料态:下拉列表(-2~-7)",
|
||||||
|
Order = 520,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "InnerDiameter2",
|
||||||
|
Label = "内径Φ2",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "手动编辑",
|
||||||
|
Order = 530,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "InnerDiameter2TolPlus",
|
||||||
|
Label = "内径上差a2",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "0.5",
|
||||||
|
Hint = "车加工态:手动编辑(默认+0.5);毛料态:下拉列表(+2~+7)",
|
||||||
|
Order = 540,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "InnerDiameter2TolMinus",
|
||||||
|
Label = "内径下差b2",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "-0.5",
|
||||||
|
Hint = "车加工态:手动编辑(默认-0.5);毛料态:下拉列表(-2~-7)",
|
||||||
|
Order = 550,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "Height1",
|
||||||
|
Label = "高度H1",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "手动编辑",
|
||||||
|
Order = 560,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "Height1TolPlus",
|
||||||
|
Label = "高度上差a3",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "0.5",
|
||||||
|
Hint = "车加工态:手动编辑(默认+0.5);毛料态:下拉列表(+2~+7)",
|
||||||
|
Order = 570,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "Height1TolMinus",
|
||||||
|
Label = "高度下差b3",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "-0.5",
|
||||||
|
Hint = "车加工态:手动编辑(默认-0.5);毛料态:下拉列表(-2~-7)",
|
||||||
|
Order = 580,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "MinWallThickness",
|
||||||
|
Label = "最小壁厚T",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "自动计算:T=(Φ1-b1+Φ2-a2)/2",
|
||||||
|
Order = 590,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "UnspecifiedFilletRadiusMax",
|
||||||
|
Label = "未注圆角半径R≤",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
EnumOptions = new List<string> { "6", "5", "4" },
|
||||||
|
Hint = "下拉列表(6/5/4),可手动编辑",
|
||||||
|
Order = 600,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "InnerRadiusMax",
|
||||||
|
Label = "内径半径R≤",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
EnumOptions = new List<string> { "8", "10" },
|
||||||
|
Hint = "仅中心冲孔结构:下拉列表(8/10),可手动编辑",
|
||||||
|
Order = 610,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "RoundHeadFilletRadiusMax",
|
||||||
|
Label = "圆头处圆角半径≤",
|
||||||
|
Type = ParamValueType.Enum,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
EnumOptions = new List<string> { "8", "10" },
|
||||||
|
Hint = "仅方体有圆头结构:下拉列表(8/10),可手动编辑",
|
||||||
|
Order = 620,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "PartDimensionsPrime",
|
||||||
|
Label = "零件尺寸(Φ'1/Φ'2/H'1等)",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "手动编辑",
|
||||||
|
Order = 630,
|
||||||
|
Group = "尺寸-环形"
|
||||||
|
},
|
||||||
|
|
||||||
|
// --- Dimensions: shaft/rod (diameter/length) ---
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "Diameter",
|
||||||
|
Label = "直径Φ",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "手动编辑",
|
||||||
|
Order = 700,
|
||||||
|
Group = "尺寸-轴杆"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "DiameterTolPlus",
|
||||||
|
Label = "直径Φ上差a1",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表(+2~+7),可手动编辑",
|
||||||
|
Order = 710,
|
||||||
|
Group = "尺寸-轴杆"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "DiameterTolMinus",
|
||||||
|
Label = "直径Φ下差b1",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表(-2~-7),可手动编辑",
|
||||||
|
Order = 720,
|
||||||
|
Group = "尺寸-轴杆"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "Length",
|
||||||
|
Label = "长度L",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "手动编辑",
|
||||||
|
Order = 730,
|
||||||
|
Group = "尺寸-轴杆"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "LengthTolPlus",
|
||||||
|
Label = "长度L上差a2",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表(+2~+7),可手动编辑",
|
||||||
|
Order = 740,
|
||||||
|
Group = "尺寸-轴杆"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "LengthTolMinus",
|
||||||
|
Label = "长度L下差b2",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表(-2~-7),可手动编辑",
|
||||||
|
Order = 750,
|
||||||
|
Group = "尺寸-轴杆"
|
||||||
|
},
|
||||||
|
|
||||||
|
// --- Dimensions: generic multi-size ---
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "Size123",
|
||||||
|
Label = "尺寸1/尺寸2/尺寸3",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "手动编辑",
|
||||||
|
Order = 800,
|
||||||
|
Group = "尺寸-通用"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "SizeTolPlusA123",
|
||||||
|
Label = "尺寸上差a1/a2/a3",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表(+2~+7),可手动编辑",
|
||||||
|
Order = 810,
|
||||||
|
Group = "尺寸-通用"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "SizeTolMinusB123",
|
||||||
|
Label = "尺寸下差b1/b2/b3",
|
||||||
|
Type = ParamValueType.String,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表(-2~-7),可手动编辑",
|
||||||
|
Order = 820,
|
||||||
|
Group = "尺寸-通用"
|
||||||
|
},
|
||||||
|
|
||||||
|
// --- Dimensions: disk (饼盘) ---
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "DiskDiameter",
|
||||||
|
Label = "直径Φ(饼盘)",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "手动编辑",
|
||||||
|
Order = 900,
|
||||||
|
Group = "尺寸-饼盘"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "DiskDiameterTolPlus",
|
||||||
|
Label = "直径Φ上差a1(饼盘)",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表(+2~+7),可手动编辑",
|
||||||
|
Order = 910,
|
||||||
|
Group = "尺寸-饼盘"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "DiskDiameterTolMinus",
|
||||||
|
Label = "直径Φ下差b1(饼盘)",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表(-2~-7),可手动编辑",
|
||||||
|
Order = 920,
|
||||||
|
Group = "尺寸-饼盘"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "DiskHeight",
|
||||||
|
Label = "高度H(饼盘)",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "手动编辑",
|
||||||
|
Order = 930,
|
||||||
|
Group = "尺寸-饼盘"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "DiskHeightTolPlus",
|
||||||
|
Label = "高度H上差a2(饼盘)",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表(+2~+7),可手动编辑",
|
||||||
|
Order = 940,
|
||||||
|
Group = "尺寸-饼盘"
|
||||||
|
},
|
||||||
|
new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = "DiskHeightTolMinus",
|
||||||
|
Label = "高度H下差b2(饼盘)",
|
||||||
|
Type = ParamValueType.Double,
|
||||||
|
Required = false,
|
||||||
|
DefaultValue = "",
|
||||||
|
Hint = "下拉列表(-2~-7),可手动编辑",
|
||||||
|
Order = 950,
|
||||||
|
Group = "尺寸-饼盘"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
118
Common/ParamCatalogStore.cs
Normal file
118
Common/ParamCatalogStore.cs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CadParamPluging.Common
|
||||||
|
{
|
||||||
|
public static class ParamCatalogStore
|
||||||
|
{
|
||||||
|
private const string FolderName = "CadParamPluging";
|
||||||
|
private const string FileName = "param-catalog.xml";
|
||||||
|
|
||||||
|
public static string GetFilePath()
|
||||||
|
{
|
||||||
|
var dir = Path.Combine(
|
||||||
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||||
|
FolderName);
|
||||||
|
return Path.Combine(dir, FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ParamCatalog Load()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var defaults = ParamCatalog.CreateDefault();
|
||||||
|
defaults.Normalize();
|
||||||
|
|
||||||
|
var path = GetFilePath();
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var stream = File.OpenRead(path))
|
||||||
|
{
|
||||||
|
var serializer = new XmlSerializer(typeof(ParamCatalog));
|
||||||
|
var obj = serializer.Deserialize(stream) as ParamCatalog;
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.Normalize();
|
||||||
|
|
||||||
|
// Merge: keep local modifications, but add any missing keys from built-in defaults.
|
||||||
|
foreach (var def in defaults.Items)
|
||||||
|
{
|
||||||
|
if (obj.FindByKey(def.Key) == null)
|
||||||
|
{
|
||||||
|
obj.Items.Add(def.Clone());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var existing = obj.FindByKey(def.Key);
|
||||||
|
if (existing != null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(existing.Label) && !string.IsNullOrWhiteSpace(def.Label))
|
||||||
|
{
|
||||||
|
existing.Label = def.Label;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(existing.Group) && !string.IsNullOrWhiteSpace(def.Group))
|
||||||
|
{
|
||||||
|
existing.Group = def.Group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migration: remove legacy demo parameters if they exist.
|
||||||
|
obj.Items = (obj.Items ?? new System.Collections.Generic.List<ParamDefinition>())
|
||||||
|
.Where(x => x != null
|
||||||
|
&& !string.Equals(x.Key, "Width", StringComparison.OrdinalIgnoreCase)
|
||||||
|
&& !string.Equals(x.Key, "Height", StringComparison.OrdinalIgnoreCase))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
obj.Normalize();
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
var defaults = ParamCatalog.CreateDefault();
|
||||||
|
defaults.Normalize();
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Save(ParamCatalog catalog)
|
||||||
|
{
|
||||||
|
if (catalog == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(catalog));
|
||||||
|
}
|
||||||
|
|
||||||
|
catalog.Normalize();
|
||||||
|
|
||||||
|
var path = GetFilePath();
|
||||||
|
var dir = Path.GetDirectoryName(path);
|
||||||
|
if (!string.IsNullOrEmpty(dir))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempPath = path + ".tmp";
|
||||||
|
var serializer = new XmlSerializer(typeof(ParamCatalog));
|
||||||
|
using (var stream = File.Create(tempPath))
|
||||||
|
{
|
||||||
|
serializer.Serialize(stream, catalog);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
File.Delete(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Move(tempPath, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
83
Common/ParamDefinition.cs
Normal file
83
Common/ParamDefinition.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace CadParamPluging.Common
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class ParamDefinition
|
||||||
|
{
|
||||||
|
public string Key { get; set; }
|
||||||
|
public string Label { get; set; }
|
||||||
|
public ParamValueType Type { get; set; }
|
||||||
|
public bool Required { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Free-form note, typically the original "填写方式".
|
||||||
|
/// </summary>
|
||||||
|
public string Hint { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stored as string for XML friendliness.
|
||||||
|
/// </summary>
|
||||||
|
public string DefaultValue { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Numeric constraints stored as string for XML friendliness.
|
||||||
|
/// </summary>
|
||||||
|
public string Min { get; set; }
|
||||||
|
public string Max { get; set; }
|
||||||
|
|
||||||
|
public List<string> EnumOptions { get; set; }
|
||||||
|
|
||||||
|
public string Group { get; set; }
|
||||||
|
public int Order { get; set; }
|
||||||
|
|
||||||
|
public ParamDefinition()
|
||||||
|
{
|
||||||
|
EnumOptions = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParamDefinition Clone()
|
||||||
|
{
|
||||||
|
return new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = Key,
|
||||||
|
Label = Label,
|
||||||
|
Type = Type,
|
||||||
|
Required = Required,
|
||||||
|
Hint = Hint,
|
||||||
|
DefaultValue = DefaultValue,
|
||||||
|
Min = Min,
|
||||||
|
Max = Max,
|
||||||
|
EnumOptions = (EnumOptions ?? new List<string>()).ToList(),
|
||||||
|
Group = Group,
|
||||||
|
Order = Order
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Normalize()
|
||||||
|
{
|
||||||
|
Key = (Key ?? string.Empty).Trim();
|
||||||
|
Label = (Label ?? string.Empty).Trim();
|
||||||
|
Hint = (Hint ?? string.Empty).Trim();
|
||||||
|
DefaultValue = (DefaultValue ?? string.Empty).Trim();
|
||||||
|
Min = (Min ?? string.Empty).Trim();
|
||||||
|
Max = (Max ?? string.Empty).Trim();
|
||||||
|
Group = (Group ?? string.Empty).Trim();
|
||||||
|
|
||||||
|
if (EnumOptions != null)
|
||||||
|
{
|
||||||
|
EnumOptions = EnumOptions
|
||||||
|
.Where(s => !string.IsNullOrWhiteSpace(s))
|
||||||
|
.Select(s => s.Trim())
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnumOptions = new List<string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Common/ParamValueType.cs
Normal file
11
Common/ParamValueType.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace CadParamPluging.Common
|
||||||
|
{
|
||||||
|
public enum ParamValueType
|
||||||
|
{
|
||||||
|
String = 0,
|
||||||
|
Int = 1,
|
||||||
|
Double = 2,
|
||||||
|
Bool = 3,
|
||||||
|
Enum = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
55
Common/TemplateKeyBuilder.cs
Normal file
55
Common/TemplateKeyBuilder.cs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using CadParamPluging.Domain.Models;
|
||||||
|
|
||||||
|
namespace CadParamPluging.Common
|
||||||
|
{
|
||||||
|
public static class TemplateKeyBuilder
|
||||||
|
{
|
||||||
|
public static string Build(TemplateParams tpl)
|
||||||
|
{
|
||||||
|
if (tpl == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Build(tpl.ProjectType, tpl.DrawingType, tpl.SheetSize, tpl.Scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Build(string projectType, string drawingType, string sheetSize, string scale)
|
||||||
|
{
|
||||||
|
var p1 = NormalizeValue(projectType);
|
||||||
|
var p2 = NormalizeValue(drawingType);
|
||||||
|
var p3 = NormalizeValue(sheetSize);
|
||||||
|
var p4 = NormalizeScale(scale);
|
||||||
|
return string.Join("|", new[] { p1, p2, p3, p4 });
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizeScale(string s)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(s))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Equals(s.Trim(), "无", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NormalizeValue(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizeValue(string s)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(s))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var trimmed = s.Trim();
|
||||||
|
var chars = trimmed.Where(c => !char.IsWhiteSpace(c)).ToArray();
|
||||||
|
return new string(chars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
48
Common/TemplateSchemaDefinition.cs
Normal file
48
Common/TemplateSchemaDefinition.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace CadParamPluging.Common
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class TemplateSchemaDefinition
|
||||||
|
{
|
||||||
|
public string TemplateKey { get; set; }
|
||||||
|
|
||||||
|
public string ProjectType { get; set; }
|
||||||
|
public string DrawingType { get; set; }
|
||||||
|
public string SheetSize { get; set; }
|
||||||
|
public string Scale { get; set; }
|
||||||
|
|
||||||
|
public string DisplayName { get; set; }
|
||||||
|
|
||||||
|
public List<string> SelectedParamKeys { get; set; }
|
||||||
|
|
||||||
|
public TemplateSchemaDefinition()
|
||||||
|
{
|
||||||
|
SelectedParamKeys = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Normalize()
|
||||||
|
{
|
||||||
|
ProjectType = (ProjectType ?? string.Empty).Trim();
|
||||||
|
DrawingType = (DrawingType ?? string.Empty).Trim();
|
||||||
|
SheetSize = (SheetSize ?? string.Empty).Trim();
|
||||||
|
Scale = (Scale ?? string.Empty).Trim();
|
||||||
|
DisplayName = (DisplayName ?? string.Empty).Trim();
|
||||||
|
|
||||||
|
TemplateKey = TemplateKeyBuilder.Build(ProjectType, DrawingType, SheetSize, Scale);
|
||||||
|
|
||||||
|
if (SelectedParamKeys == null)
|
||||||
|
{
|
||||||
|
SelectedParamKeys = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectedParamKeys = SelectedParamKeys
|
||||||
|
.Where(s => !string.IsNullOrWhiteSpace(s))
|
||||||
|
.Select(s => s.Trim())
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
89
Common/TemplateSchemaStore.cs
Normal file
89
Common/TemplateSchemaStore.cs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CadParamPluging.Common
|
||||||
|
{
|
||||||
|
public static class TemplateSchemaStore
|
||||||
|
{
|
||||||
|
private const string FolderName = "CadParamPluging";
|
||||||
|
private const string FileName = "template-schemas.xml";
|
||||||
|
|
||||||
|
public static string GetFilePath()
|
||||||
|
{
|
||||||
|
var dir = Path.Combine(
|
||||||
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||||
|
FolderName);
|
||||||
|
return Path.Combine(dir, FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TemplateSchemas Load()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var path = GetFilePath();
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
return new TemplateSchemas();
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var stream = File.OpenRead(path))
|
||||||
|
{
|
||||||
|
var serializer = new XmlSerializer(typeof(TemplateSchemas));
|
||||||
|
var obj = serializer.Deserialize(stream) as TemplateSchemas;
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
return new TemplateSchemas();
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.Normalize();
|
||||||
|
if (obj.Items != null)
|
||||||
|
{
|
||||||
|
obj.Items = obj.Items
|
||||||
|
.Where(x => x != null && !string.IsNullOrWhiteSpace(x.TemplateKey))
|
||||||
|
.GroupBy(x => x.TemplateKey, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.Select(g => g.First())
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new TemplateSchemas();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Save(TemplateSchemas schemas)
|
||||||
|
{
|
||||||
|
if (schemas == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(schemas));
|
||||||
|
}
|
||||||
|
|
||||||
|
schemas.Normalize();
|
||||||
|
|
||||||
|
var path = GetFilePath();
|
||||||
|
var dir = Path.GetDirectoryName(path);
|
||||||
|
if (!string.IsNullOrEmpty(dir))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempPath = path + ".tmp";
|
||||||
|
var serializer = new XmlSerializer(typeof(TemplateSchemas));
|
||||||
|
using (var stream = File.Create(tempPath))
|
||||||
|
{
|
||||||
|
serializer.Serialize(stream, schemas);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
File.Delete(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Move(tempPath, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Common/TemplateSchemas.cs
Normal file
29
Common/TemplateSchemas.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace CadParamPluging.Common
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class TemplateSchemas
|
||||||
|
{
|
||||||
|
public List<TemplateSchemaDefinition> Items { get; set; }
|
||||||
|
|
||||||
|
public TemplateSchemas()
|
||||||
|
{
|
||||||
|
Items = new List<TemplateSchemaDefinition>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Normalize()
|
||||||
|
{
|
||||||
|
if (Items == null)
|
||||||
|
{
|
||||||
|
Items = new List<TemplateSchemaDefinition>();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var it in Items)
|
||||||
|
{
|
||||||
|
it?.Normalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -41,10 +41,7 @@ namespace CadParamPluging.Domain
|
|||||||
throw new BusinessException("请填写项目类型和图纸类型。");
|
throw new BusinessException("请填写项目类型和图纸类型。");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawingParams == null || !drawingParams.HasValidSize())
|
// 出图参数由不同模板决定,后续由模板对应的生成器做更精细的校验。
|
||||||
{
|
|
||||||
throw new BusinessException("请填写有效的出图尺寸(宽度和高度需大于 0)。");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawByParams(TemplateInfo template, DrawingParams drawingParams, CadDrawingService cadService)
|
public static void DrawByParams(TemplateInfo template, DrawingParams drawingParams, CadDrawingService cadService)
|
||||||
|
|||||||
301
UI/DrawingParamsForm.cs
Normal file
301
UI/DrawingParamsForm.cs
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using CadParamPluging.Common;
|
||||||
|
|
||||||
|
namespace CadParamPluging.UI
|
||||||
|
{
|
||||||
|
public class DrawingParamsForm : Form
|
||||||
|
{
|
||||||
|
private readonly TableLayoutPanel _grid;
|
||||||
|
private readonly Dictionary<string, Control> _controlsByKey;
|
||||||
|
private readonly ParamCatalog _catalog;
|
||||||
|
private readonly TemplateSchemaDefinition _schema;
|
||||||
|
private readonly ToolTip _toolTip;
|
||||||
|
|
||||||
|
public ParamBag Result { get; private set; }
|
||||||
|
|
||||||
|
public DrawingParamsForm(ParamCatalog catalog, TemplateSchemaDefinition schema)
|
||||||
|
{
|
||||||
|
_catalog = (catalog ?? ParamCatalog.CreateDefault()).Clone();
|
||||||
|
_catalog.Normalize();
|
||||||
|
_schema = schema;
|
||||||
|
|
||||||
|
Text = "填写参数";
|
||||||
|
Size = new Size(560, 620);
|
||||||
|
StartPosition = FormStartPosition.CenterParent;
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
ShowInTaskbar = false;
|
||||||
|
|
||||||
|
_controlsByKey = new Dictionary<string, Control>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
_toolTip = new ToolTip();
|
||||||
|
|
||||||
|
var root = new TableLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
Padding = new Padding(10),
|
||||||
|
ColumnCount = 1,
|
||||||
|
RowCount = 3
|
||||||
|
};
|
||||||
|
root.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||||
|
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100f));
|
||||||
|
root.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||||
|
|
||||||
|
var header = new Label
|
||||||
|
{
|
||||||
|
AutoSize = true,
|
||||||
|
ForeColor = Color.DarkBlue,
|
||||||
|
Text = BuildHeaderText(schema)
|
||||||
|
};
|
||||||
|
|
||||||
|
var scrollPanel = new Panel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
AutoScroll = true
|
||||||
|
};
|
||||||
|
|
||||||
|
_grid = new TableLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Top,
|
||||||
|
AutoSize = true,
|
||||||
|
ColumnCount = 2,
|
||||||
|
RowCount = 1,
|
||||||
|
Padding = new Padding(0)
|
||||||
|
};
|
||||||
|
_grid.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
|
||||||
|
_grid.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
|
||||||
|
|
||||||
|
BuildFields();
|
||||||
|
|
||||||
|
scrollPanel.Controls.Add(_grid);
|
||||||
|
|
||||||
|
var buttons = new FlowLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
FlowDirection = FlowDirection.RightToLeft,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
var btnCancel = new Button { Text = "取消", DialogResult = DialogResult.Cancel };
|
||||||
|
var btnOk = new Button { Text = "确定" };
|
||||||
|
btnOk.Click += (_, __) => OnOk();
|
||||||
|
buttons.Controls.Add(btnCancel);
|
||||||
|
buttons.Controls.Add(btnOk);
|
||||||
|
|
||||||
|
root.Controls.Add(header, 0, 0);
|
||||||
|
root.Controls.Add(scrollPanel, 0, 1);
|
||||||
|
root.Controls.Add(buttons, 0, 2);
|
||||||
|
|
||||||
|
Controls.Add(root);
|
||||||
|
AcceptButton = btnOk;
|
||||||
|
CancelButton = btnCancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BuildHeaderText(TemplateSchemaDefinition schema)
|
||||||
|
{
|
||||||
|
if (schema == null)
|
||||||
|
{
|
||||||
|
return "模板参数未配置。";
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = string.IsNullOrWhiteSpace(schema.DisplayName) ? "(未命名模板)" : schema.DisplayName;
|
||||||
|
return $"模板: {name} | {schema.ProjectType}/{schema.DrawingType}/{schema.SheetSize}/{schema.Scale}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildFields()
|
||||||
|
{
|
||||||
|
var keys = (_schema?.SelectedParamKeys ?? new List<string>()).ToList();
|
||||||
|
if (keys.Count == 0)
|
||||||
|
{
|
||||||
|
var rowIdx = _grid.RowCount++;
|
||||||
|
_grid.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||||
|
_grid.Controls.Add(new Label { AutoSize = true, Text = "(该模板未绑定任何参数)" }, 0, rowIdx);
|
||||||
|
_grid.SetColumnSpan(_grid.Controls[_grid.Controls.Count - 1], 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var key in keys)
|
||||||
|
{
|
||||||
|
var def = _catalog.FindByKey(key);
|
||||||
|
if (def == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddField(def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddField(ParamDefinition def)
|
||||||
|
{
|
||||||
|
var rowIdx = _grid.RowCount++;
|
||||||
|
_grid.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||||
|
|
||||||
|
var labelText = def.Label;
|
||||||
|
if (def.Required)
|
||||||
|
{
|
||||||
|
labelText += " *";
|
||||||
|
}
|
||||||
|
|
||||||
|
var lbl = new Label { AutoSize = true, Text = labelText, TextAlign = ContentAlignment.MiddleLeft, Padding = new Padding(0, 6, 8, 6) };
|
||||||
|
var ctrl = CreateControl(def);
|
||||||
|
ctrl.Width = 260;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(def.Hint))
|
||||||
|
{
|
||||||
|
_toolTip.SetToolTip(lbl, def.Hint);
|
||||||
|
_toolTip.SetToolTip(ctrl, def.Hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
_grid.Controls.Add(lbl, 0, rowIdx);
|
||||||
|
_grid.Controls.Add(ctrl, 1, rowIdx);
|
||||||
|
_controlsByKey[def.Key] = ctrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Control CreateControl(ParamDefinition def)
|
||||||
|
{
|
||||||
|
switch (def.Type)
|
||||||
|
{
|
||||||
|
case ParamValueType.Bool:
|
||||||
|
return new CheckBox { Checked = ParseBool(def.DefaultValue), AutoSize = true };
|
||||||
|
case ParamValueType.Enum:
|
||||||
|
return CreateEnumCombo(def);
|
||||||
|
case ParamValueType.Int:
|
||||||
|
return CreateNumber(def, isInt: true);
|
||||||
|
case ParamValueType.Double:
|
||||||
|
return CreateNumber(def, isInt: false);
|
||||||
|
default:
|
||||||
|
return new TextBox { Text = def.DefaultValue ?? string.Empty };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ParseBool(string s)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(s))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bool.TryParse(s, out var v))
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
return string.Equals(s.Trim(), "1", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(s.Trim(), "是", StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ComboBox CreateEnumCombo(ParamDefinition def)
|
||||||
|
{
|
||||||
|
// Allow manual edit to match many "下拉列表...可手动编辑" cases.
|
||||||
|
var cb = new ComboBox { DropDownStyle = ComboBoxStyle.DropDown };
|
||||||
|
var arr = (def.EnumOptions ?? new List<string>()).Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).ToArray();
|
||||||
|
if (arr.Length > 0)
|
||||||
|
{
|
||||||
|
cb.Items.AddRange(arr);
|
||||||
|
var idx = Array.FindIndex(arr, x => string.Equals(x, def.DefaultValue, StringComparison.OrdinalIgnoreCase));
|
||||||
|
cb.SelectedIndex = idx >= 0 ? idx : 0;
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrWhiteSpace(def.DefaultValue))
|
||||||
|
{
|
||||||
|
cb.Text = def.DefaultValue;
|
||||||
|
}
|
||||||
|
return cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Control CreateNumber(ParamDefinition def, bool isInt)
|
||||||
|
{
|
||||||
|
var num = new NumericUpDown
|
||||||
|
{
|
||||||
|
DecimalPlaces = isInt ? 0 : 3,
|
||||||
|
Minimum = -1000000000,
|
||||||
|
Maximum = 1000000000,
|
||||||
|
ThousandsSeparator = true
|
||||||
|
};
|
||||||
|
|
||||||
|
if (TryParseDecimal(def.Min, out var min))
|
||||||
|
{
|
||||||
|
num.Minimum = min;
|
||||||
|
}
|
||||||
|
if (TryParseDecimal(def.Max, out var max))
|
||||||
|
{
|
||||||
|
num.Maximum = max;
|
||||||
|
}
|
||||||
|
if (TryParseDecimal(def.DefaultValue, out var dv))
|
||||||
|
{
|
||||||
|
if (dv < num.Minimum) dv = num.Minimum;
|
||||||
|
if (dv > num.Maximum) dv = num.Maximum;
|
||||||
|
num.Value = dv;
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryParseDecimal(string s, out decimal value)
|
||||||
|
{
|
||||||
|
value = 0;
|
||||||
|
if (string.IsNullOrWhiteSpace(s))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (decimal.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return decimal.TryParse(s, NumberStyles.Float, CultureInfo.CurrentCulture, out value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOk()
|
||||||
|
{
|
||||||
|
var bag = new ParamBag();
|
||||||
|
foreach (var key in _controlsByKey.Keys.ToList())
|
||||||
|
{
|
||||||
|
if (!_controlsByKey.TryGetValue(key, out var ctrl) || ctrl == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var def = _catalog.FindByKey(key);
|
||||||
|
if (def == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = ReadValue(ctrl, def);
|
||||||
|
if (def.Required && string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, $"请填写:{def.Label} ({def.Key})", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
ctrl.Focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bag.Set(def.Key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = bag;
|
||||||
|
DialogResult = DialogResult.OK;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ReadValue(Control ctrl, ParamDefinition def)
|
||||||
|
{
|
||||||
|
switch (def.Type)
|
||||||
|
{
|
||||||
|
case ParamValueType.Bool:
|
||||||
|
return (ctrl as CheckBox)?.Checked == true ? "true" : "false";
|
||||||
|
case ParamValueType.Enum:
|
||||||
|
return ((ctrl as ComboBox)?.Text ?? string.Empty).Trim();
|
||||||
|
case ParamValueType.Int:
|
||||||
|
case ParamValueType.Double:
|
||||||
|
if (ctrl is NumericUpDown num)
|
||||||
|
{
|
||||||
|
return num.Value.ToString(CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
default:
|
||||||
|
return ((ctrl as TextBox)?.Text ?? string.Empty).Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
222
UI/ParamCatalogForm.cs
Normal file
222
UI/ParamCatalogForm.cs
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using CadParamPluging.Common;
|
||||||
|
|
||||||
|
namespace CadParamPluging.UI
|
||||||
|
{
|
||||||
|
public class ParamCatalogForm : Form
|
||||||
|
{
|
||||||
|
private readonly ListBox _list;
|
||||||
|
private ParamCatalog _catalog;
|
||||||
|
|
||||||
|
public ParamCatalogForm(ParamCatalog initial)
|
||||||
|
{
|
||||||
|
Text = "参数总表";
|
||||||
|
Size = new Size(640, 520);
|
||||||
|
StartPosition = FormStartPosition.CenterParent;
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
ShowInTaskbar = false;
|
||||||
|
|
||||||
|
_catalog = (initial ?? ParamCatalog.CreateDefault()).Clone();
|
||||||
|
_catalog.Normalize();
|
||||||
|
|
||||||
|
var layout = new TableLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
Padding = new Padding(10),
|
||||||
|
ColumnCount = 2,
|
||||||
|
RowCount = 2
|
||||||
|
};
|
||||||
|
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
|
||||||
|
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
|
||||||
|
layout.RowStyles.Add(new RowStyle(SizeType.Percent, 100f));
|
||||||
|
layout.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||||
|
|
||||||
|
_list = new ListBox { Dock = DockStyle.Fill };
|
||||||
|
ReloadList();
|
||||||
|
|
||||||
|
var actions = new FlowLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
FlowDirection = FlowDirection.TopDown,
|
||||||
|
WrapContents = false,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var btnAdd = new Button { Text = "新增", AutoSize = true };
|
||||||
|
btnAdd.Click += (_, __) => OnAdd();
|
||||||
|
var btnEdit = new Button { Text = "修改", AutoSize = true };
|
||||||
|
btnEdit.Click += (_, __) => OnEdit();
|
||||||
|
var btnDelete = new Button { Text = "删除", AutoSize = true };
|
||||||
|
btnDelete.Click += (_, __) => OnDelete();
|
||||||
|
|
||||||
|
actions.Controls.Add(btnAdd);
|
||||||
|
actions.Controls.Add(btnEdit);
|
||||||
|
actions.Controls.Add(btnDelete);
|
||||||
|
|
||||||
|
var btnPanel = new FlowLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
FlowDirection = FlowDirection.RightToLeft,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
var btnClose = new Button { Text = "关闭", DialogResult = DialogResult.Cancel };
|
||||||
|
var btnSave = new Button { Text = "保存" };
|
||||||
|
btnSave.Click += (_, __) => OnSave();
|
||||||
|
btnPanel.Controls.Add(btnClose);
|
||||||
|
btnPanel.Controls.Add(btnSave);
|
||||||
|
|
||||||
|
layout.Controls.Add(_list, 0, 0);
|
||||||
|
layout.Controls.Add(actions, 1, 0);
|
||||||
|
layout.Controls.Add(btnPanel, 0, 1);
|
||||||
|
layout.SetColumnSpan(btnPanel, 2);
|
||||||
|
|
||||||
|
Controls.Add(layout);
|
||||||
|
CancelButton = btnClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReloadList()
|
||||||
|
{
|
||||||
|
_list.Items.Clear();
|
||||||
|
foreach (var it in (_catalog.Items ?? Enumerable.Empty<ParamDefinition>()).OrderBy(x => x.Order))
|
||||||
|
{
|
||||||
|
_list.Items.Add(Format(it));
|
||||||
|
}
|
||||||
|
if (_list.Items.Count > 0)
|
||||||
|
{
|
||||||
|
_list.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string Format(ParamDefinition def)
|
||||||
|
{
|
||||||
|
if (def == null)
|
||||||
|
{
|
||||||
|
return "(null)";
|
||||||
|
}
|
||||||
|
var label = string.IsNullOrWhiteSpace(def.Label) ? def.Key : def.Label;
|
||||||
|
return $"{label} ({def.Key}) [{def.Type}]";
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParamDefinition GetSelected()
|
||||||
|
{
|
||||||
|
var idx = _list.SelectedIndex;
|
||||||
|
if (idx < 0 || _catalog.Items == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ordered = _catalog.Items.OrderBy(x => x.Order).ThenBy(x => x.Key, StringComparer.OrdinalIgnoreCase).ToList();
|
||||||
|
if (idx >= ordered.Count)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selKey = ordered[idx].Key;
|
||||||
|
return _catalog.FindByKey(selKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAdd()
|
||||||
|
{
|
||||||
|
using (var f = new ParamDefinitionForm("新增参数", new ParamDefinition { Type = ParamValueType.String }, isEdit: false))
|
||||||
|
{
|
||||||
|
if (f.ShowDialog(this) != DialogResult.OK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var def = f.Result;
|
||||||
|
if (_catalog.FindByKey(def.Key) != null)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, $"Key 已存在:{def.Key}", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_catalog.Items.Add(def);
|
||||||
|
_catalog.Normalize();
|
||||||
|
ReloadList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEdit()
|
||||||
|
{
|
||||||
|
var selected = GetSelected();
|
||||||
|
if (selected == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, "请先选择一项再修改。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var f = new ParamDefinitionForm("修改参数", selected, isEdit: true))
|
||||||
|
{
|
||||||
|
if (f.ShowDialog(this) != DialogResult.OK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var updated = f.Result;
|
||||||
|
var existing = _catalog.FindByKey(updated.Key);
|
||||||
|
if (existing == null)
|
||||||
|
{
|
||||||
|
_catalog.Items.Add(updated);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
existing.Label = updated.Label;
|
||||||
|
existing.Type = updated.Type;
|
||||||
|
existing.Required = updated.Required;
|
||||||
|
existing.Hint = updated.Hint;
|
||||||
|
existing.DefaultValue = updated.DefaultValue;
|
||||||
|
existing.Min = updated.Min;
|
||||||
|
existing.Max = updated.Max;
|
||||||
|
existing.EnumOptions = updated.EnumOptions;
|
||||||
|
existing.Group = updated.Group;
|
||||||
|
existing.Order = updated.Order;
|
||||||
|
existing.Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
_catalog.Normalize();
|
||||||
|
ReloadList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDelete()
|
||||||
|
{
|
||||||
|
var selected = GetSelected();
|
||||||
|
if (selected == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, "请先选择一项再删除。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var confirm = MessageBox.Show(this, $"确认删除参数:{selected.Label} ({selected.Key})?", "删除", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
|
||||||
|
if (confirm != DialogResult.Yes)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_catalog.Items = (_catalog.Items ?? Enumerable.Empty<ParamDefinition>())
|
||||||
|
.Where(x => !string.Equals(x.Key, selected.Key, StringComparison.OrdinalIgnoreCase))
|
||||||
|
.ToList();
|
||||||
|
_catalog.Normalize();
|
||||||
|
ReloadList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSave()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ParamCatalogStore.Save(_catalog);
|
||||||
|
MessageBox.Show(this, "已保存。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, $"保存失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
297
UI/ParamDefinitionForm.cs
Normal file
297
UI/ParamDefinitionForm.cs
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using CadParamPluging.Common;
|
||||||
|
|
||||||
|
namespace CadParamPluging.UI
|
||||||
|
{
|
||||||
|
public class ParamDefinitionForm : Form
|
||||||
|
{
|
||||||
|
private readonly bool _isEdit;
|
||||||
|
private readonly TextBox _txtKey;
|
||||||
|
private readonly TextBox _txtLabel;
|
||||||
|
private readonly ComboBox _cbType;
|
||||||
|
private readonly CheckBox _chkRequired;
|
||||||
|
private readonly TextBox _txtHint;
|
||||||
|
private readonly TextBox _txtDefault;
|
||||||
|
private readonly TextBox _txtMin;
|
||||||
|
private readonly TextBox _txtMax;
|
||||||
|
private readonly TextBox _txtEnumOptions;
|
||||||
|
private readonly TextBox _txtGroup;
|
||||||
|
private readonly NumericUpDown _numOrder;
|
||||||
|
|
||||||
|
public ParamDefinition Result { get; private set; }
|
||||||
|
|
||||||
|
public ParamDefinitionForm(string title, ParamDefinition initial, bool isEdit)
|
||||||
|
{
|
||||||
|
_isEdit = isEdit;
|
||||||
|
|
||||||
|
Text = title;
|
||||||
|
Size = new Size(520, 520);
|
||||||
|
StartPosition = FormStartPosition.CenterParent;
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
ShowInTaskbar = false;
|
||||||
|
|
||||||
|
var def = (initial ?? new ParamDefinition()).Clone();
|
||||||
|
def.Normalize();
|
||||||
|
|
||||||
|
var layout = new TableLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
Padding = new Padding(10),
|
||||||
|
ColumnCount = 2,
|
||||||
|
RowCount = 12,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
|
||||||
|
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
|
||||||
|
|
||||||
|
_txtKey = new TextBox { Width = 260, Text = def.Key };
|
||||||
|
_txtLabel = new TextBox { Width = 260, Text = def.Label };
|
||||||
|
_cbType = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Width = 260 };
|
||||||
|
_cbType.Items.AddRange(Enum.GetNames(typeof(ParamValueType)));
|
||||||
|
_cbType.SelectedItem = def.Type.ToString();
|
||||||
|
_cbType.SelectedIndexChanged += (_, __) => UpdateTypeUi();
|
||||||
|
|
||||||
|
_chkRequired = new CheckBox { Text = "必填", Checked = def.Required, AutoSize = true };
|
||||||
|
_txtHint = new TextBox { Width = 260, Text = def.Hint, Multiline = true, Height = 60, ScrollBars = ScrollBars.Vertical };
|
||||||
|
_txtDefault = new TextBox { Width = 260, Text = def.DefaultValue };
|
||||||
|
_txtMin = new TextBox { Width = 260, Text = def.Min };
|
||||||
|
_txtMax = new TextBox { Width = 260, Text = def.Max };
|
||||||
|
_txtEnumOptions = new TextBox { Width = 260, Height = 120, Multiline = true, ScrollBars = ScrollBars.Vertical };
|
||||||
|
_txtEnumOptions.Text = string.Join(Environment.NewLine, def.EnumOptions ?? new List<string>());
|
||||||
|
_txtGroup = new TextBox { Width = 260, Text = def.Group };
|
||||||
|
_numOrder = new NumericUpDown { Width = 120, Minimum = -100000, Maximum = 100000, Value = def.Order };
|
||||||
|
|
||||||
|
if (_isEdit)
|
||||||
|
{
|
||||||
|
_txtKey.ReadOnly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var row = 0;
|
||||||
|
layout.Controls.Add(new Label { Text = "Key(英文)", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
layout.Controls.Add(_txtKey, 1, row++);
|
||||||
|
|
||||||
|
layout.Controls.Add(new Label { Text = "Label(中文)", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
layout.Controls.Add(_txtLabel, 1, row++);
|
||||||
|
|
||||||
|
layout.Controls.Add(new Label { Text = "类型", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
layout.Controls.Add(_cbType, 1, row++);
|
||||||
|
|
||||||
|
layout.Controls.Add(new Label { Text = "", AutoSize = true }, 0, row);
|
||||||
|
layout.Controls.Add(_chkRequired, 1, row++);
|
||||||
|
|
||||||
|
layout.Controls.Add(new Label { Text = "提示/填写方式", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
layout.Controls.Add(_txtHint, 1, row++);
|
||||||
|
|
||||||
|
layout.Controls.Add(new Label { Text = "默认值", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
layout.Controls.Add(_txtDefault, 1, row++);
|
||||||
|
|
||||||
|
layout.Controls.Add(new Label { Text = "最小值(数字)", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
layout.Controls.Add(_txtMin, 1, row++);
|
||||||
|
|
||||||
|
layout.Controls.Add(new Label { Text = "最大值(数字)", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
layout.Controls.Add(_txtMax, 1, row++);
|
||||||
|
|
||||||
|
layout.Controls.Add(new Label { Text = "枚举选项(每行一项)", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
layout.Controls.Add(_txtEnumOptions, 1, row++);
|
||||||
|
|
||||||
|
layout.Controls.Add(new Label { Text = "分组", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
layout.Controls.Add(_txtGroup, 1, row++);
|
||||||
|
|
||||||
|
layout.Controls.Add(new Label { Text = "排序", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
layout.Controls.Add(_numOrder, 1, row++);
|
||||||
|
|
||||||
|
var btnPanel = new FlowLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
FlowDirection = FlowDirection.RightToLeft,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
var btnCancel = new Button { Text = "取消", DialogResult = DialogResult.Cancel };
|
||||||
|
var btnOk = new Button { Text = "确定" };
|
||||||
|
btnOk.Click += (_, __) => OnOk();
|
||||||
|
btnPanel.Controls.Add(btnCancel);
|
||||||
|
btnPanel.Controls.Add(btnOk);
|
||||||
|
|
||||||
|
layout.Controls.Add(btnPanel, 0, row);
|
||||||
|
layout.SetColumnSpan(btnPanel, 2);
|
||||||
|
|
||||||
|
Controls.Add(layout);
|
||||||
|
AcceptButton = btnOk;
|
||||||
|
CancelButton = btnCancel;
|
||||||
|
|
||||||
|
UpdateTypeUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTypeUi()
|
||||||
|
{
|
||||||
|
var type = GetSelectedType();
|
||||||
|
var showEnum = type == ParamValueType.Enum;
|
||||||
|
_txtEnumOptions.Enabled = showEnum;
|
||||||
|
|
||||||
|
var showMinMax = type == ParamValueType.Int || type == ParamValueType.Double;
|
||||||
|
_txtMin.Enabled = showMinMax;
|
||||||
|
_txtMax.Enabled = showMinMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParamValueType GetSelectedType()
|
||||||
|
{
|
||||||
|
var selected = _cbType.SelectedItem as string;
|
||||||
|
if (Enum.TryParse(selected, out ParamValueType t))
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParamValueType.String;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOk()
|
||||||
|
{
|
||||||
|
var key = (_txtKey.Text ?? string.Empty).Trim();
|
||||||
|
var label = (_txtLabel.Text ?? string.Empty).Trim();
|
||||||
|
|
||||||
|
if (key.Length == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, "Key 不能为空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsValidKey(key))
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, "Key 格式不合法:必须以字母开头,仅允许字母/数字/下划线。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (label.Length == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, "Label 不能为空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var type = GetSelectedType();
|
||||||
|
|
||||||
|
var def = new ParamDefinition
|
||||||
|
{
|
||||||
|
Key = key,
|
||||||
|
Label = label,
|
||||||
|
Type = type,
|
||||||
|
Required = _chkRequired.Checked,
|
||||||
|
Hint = (_txtHint.Text ?? string.Empty).Trim(),
|
||||||
|
DefaultValue = (_txtDefault.Text ?? string.Empty).Trim(),
|
||||||
|
Min = (_txtMin.Text ?? string.Empty).Trim(),
|
||||||
|
Max = (_txtMax.Text ?? string.Empty).Trim(),
|
||||||
|
Group = (_txtGroup.Text ?? string.Empty).Trim(),
|
||||||
|
Order = (int)_numOrder.Value,
|
||||||
|
EnumOptions = ParseLines(_txtEnumOptions.Text)
|
||||||
|
};
|
||||||
|
def.Normalize();
|
||||||
|
|
||||||
|
var err = ValidateDefinition(def);
|
||||||
|
if (err != null)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, err, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = def;
|
||||||
|
DialogResult = DialogResult.OK;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<string> ParseLines(string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
return new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return text
|
||||||
|
.Replace("\r\n", "\n")
|
||||||
|
.Replace("\r", "\n")
|
||||||
|
.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.Select(s => (s ?? string.Empty).Trim())
|
||||||
|
.Where(s => s.Length > 0)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsValidKey(string key)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(key))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!char.IsLetter(key[0]))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var ch in key)
|
||||||
|
{
|
||||||
|
if (char.IsLetterOrDigit(ch) || ch == '_')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ValidateDefinition(ParamDefinition def)
|
||||||
|
{
|
||||||
|
if (def == null)
|
||||||
|
{
|
||||||
|
return "参数定义不能为空。";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def.Type == ParamValueType.Enum && (def.EnumOptions == null || def.EnumOptions.Count == 0))
|
||||||
|
{
|
||||||
|
return "Enum 类型必须提供至少 1 个枚举选项。";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((def.Type == ParamValueType.Int || def.Type == ParamValueType.Double) && (def.Min.Length > 0 || def.Max.Length > 0))
|
||||||
|
{
|
||||||
|
if (!TryParseDouble(def.Min, out var min, allowEmpty: true))
|
||||||
|
{
|
||||||
|
return "最小值不是有效数字。";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TryParseDouble(def.Max, out var max, allowEmpty: true))
|
||||||
|
{
|
||||||
|
return "最大值不是有效数字。";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def.Min.Length > 0 && def.Max.Length > 0 && min > max)
|
||||||
|
{
|
||||||
|
return "最小值不能大于最大值。";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryParseDouble(string text, out double value, bool allowEmpty)
|
||||||
|
{
|
||||||
|
value = 0;
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
return allowEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var s = text.Trim();
|
||||||
|
if (double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out value))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return double.TryParse(s, NumberStyles.Float, CultureInfo.CurrentCulture, out value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,8 +20,6 @@ namespace CadParamPluging.UI
|
|||||||
private readonly ComboBox _cbDrawingType;
|
private readonly ComboBox _cbDrawingType;
|
||||||
private readonly ComboBox _cbSheetSize;
|
private readonly ComboBox _cbSheetSize;
|
||||||
private readonly ComboBox _cbScale;
|
private readonly ComboBox _cbScale;
|
||||||
private readonly TextBox _txtWidth;
|
|
||||||
private readonly TextBox _txtHeight;
|
|
||||||
private Label _lblTemplateInfo;
|
private Label _lblTemplateInfo;
|
||||||
private TextBox _txtLog;
|
private TextBox _txtLog;
|
||||||
private TextBox _txtTemplatePath;
|
private TextBox _txtTemplatePath;
|
||||||
@ -53,8 +51,6 @@ namespace CadParamPluging.UI
|
|||||||
_cbDrawingType = CreateComboBox(dropdownOptions.ProcessMethods);
|
_cbDrawingType = CreateComboBox(dropdownOptions.ProcessMethods);
|
||||||
_cbSheetSize = CreateComboBox(dropdownOptions.StructuralFeatures);
|
_cbSheetSize = CreateComboBox(dropdownOptions.StructuralFeatures);
|
||||||
_cbScale = CreateComboBox(dropdownOptions.SpecialConditions);
|
_cbScale = CreateComboBox(dropdownOptions.SpecialConditions);
|
||||||
_txtWidth = CreateTextBox("5000");
|
|
||||||
_txtHeight = CreateTextBox("3000");
|
|
||||||
|
|
||||||
var templateGroup = BuildTemplateGroup();
|
var templateGroup = BuildTemplateGroup();
|
||||||
var drawingGroup = BuildDrawingGroup();
|
var drawingGroup = BuildDrawingGroup();
|
||||||
@ -135,21 +131,14 @@ namespace CadParamPluging.UI
|
|||||||
AutoSizeMode = AutoSizeMode.GrowAndShrink
|
AutoSizeMode = AutoSizeMode.GrowAndShrink
|
||||||
};
|
};
|
||||||
|
|
||||||
var grid = new TableLayoutPanel
|
var label = new Label
|
||||||
{
|
{
|
||||||
Dock = DockStyle.Fill,
|
AutoSize = true,
|
||||||
ColumnCount = 2,
|
Padding = new Padding(8),
|
||||||
RowCount = 3,
|
Text = "出图参数较多,请点击【生成图纸】后在弹窗中填写。"
|
||||||
AutoSize = true
|
|
||||||
};
|
};
|
||||||
|
|
||||||
grid.Controls.Add(new Label { Text = "宽度(mm)", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, 0);
|
group.Controls.Add(label);
|
||||||
grid.Controls.Add(_txtWidth, 1, 0);
|
|
||||||
|
|
||||||
grid.Controls.Add(new Label { Text = "高度(mm)", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, 1);
|
|
||||||
grid.Controls.Add(_txtHeight, 1, 1);
|
|
||||||
|
|
||||||
group.Controls.Add(grid);
|
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,7 +513,6 @@ namespace CadParamPluging.UI
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var tplParams = CollectTemplateParams();
|
var tplParams = CollectTemplateParams();
|
||||||
var drawingParams = CollectDrawingParams();
|
|
||||||
|
|
||||||
if (_selectedTemplate == null || string.IsNullOrWhiteSpace(_selectedTemplate.FilePath))
|
if (_selectedTemplate == null || string.IsNullOrWhiteSpace(_selectedTemplate.FilePath))
|
||||||
{
|
{
|
||||||
@ -542,6 +530,39 @@ namespace CadParamPluging.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var templateKey = TemplateKeyBuilder.Build(tplParams);
|
||||||
|
if (string.IsNullOrWhiteSpace(templateKey))
|
||||||
|
{
|
||||||
|
AppendLog("模板参数不完整,无法生成 TemplateKey。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var schemas = TemplateSchemaStore.Load();
|
||||||
|
var schema = (schemas?.Items ?? Enumerable.Empty<TemplateSchemaDefinition>())
|
||||||
|
.FirstOrDefault(s => string.Equals(s.TemplateKey, templateKey, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (schema == null)
|
||||||
|
{
|
||||||
|
AppendLog($"未找到该模板的参数绑定配置(TemplateKey={templateKey})。请到【设置→模板参数绑定】中新增/配置。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var catalog = ParamCatalogStore.Load();
|
||||||
|
CadParamPluging.Common.ParamBag bag;
|
||||||
|
using (var f = new DrawingParamsForm(catalog, schema))
|
||||||
|
{
|
||||||
|
var r = f.ShowDialog(this);
|
||||||
|
if (r != DialogResult.OK)
|
||||||
|
{
|
||||||
|
AppendLog("用户取消填写参数。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bag = f.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Current demo generator uses a rectangle. Size defaults are handled inside DomainFacade.DrawByParams.
|
||||||
|
// Real templates will use their own generator/parameters.
|
||||||
|
var drawingParams = new DrawingParams();
|
||||||
|
|
||||||
DomainFacade.ValidateParameters(tplParams, drawingParams);
|
DomainFacade.ValidateParameters(tplParams, drawingParams);
|
||||||
|
|
||||||
var doc = TemplateDrawingService.CreateDocumentFromTemplate(_selectedTemplate);
|
var doc = TemplateDrawingService.CreateDocumentFromTemplate(_selectedTemplate);
|
||||||
@ -669,15 +690,6 @@ namespace CadParamPluging.UI
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private DrawingParams CollectDrawingParams()
|
|
||||||
{
|
|
||||||
return new DrawingParams
|
|
||||||
{
|
|
||||||
Width = ParseDouble(_txtWidth.Text),
|
|
||||||
Height = ParseDouble(_txtHeight.Text)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ComboBox CreateComboBox(System.Collections.Generic.IEnumerable<string> items)
|
private static ComboBox CreateComboBox(System.Collections.Generic.IEnumerable<string> items)
|
||||||
{
|
{
|
||||||
var cb = new ComboBox
|
var cb = new ComboBox
|
||||||
@ -725,25 +737,6 @@ namespace CadParamPluging.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextBox CreateTextBox(string defaultText)
|
|
||||||
{
|
|
||||||
return new TextBox { Width = 160, Text = defaultText };
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double ParseDouble(string text)
|
|
||||||
{
|
|
||||||
if (double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var value))
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (double.TryParse(text, NumberStyles.Float, CultureInfo.CurrentCulture, out value))
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AppendLog(string message)
|
private void AppendLog(string message)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -57,8 +57,32 @@ namespace CadParamPluging.UI
|
|||||||
tabs.TabPages.Add(BuildEditableTab("结构特征", _lbStructuralFeatures));
|
tabs.TabPages.Add(BuildEditableTab("结构特征", _lbStructuralFeatures));
|
||||||
tabs.TabPages.Add(BuildEditableTab("特殊条件", _lbSpecialConditions));
|
tabs.TabPages.Add(BuildEditableTab("特殊条件", _lbSpecialConditions));
|
||||||
|
|
||||||
// Bottom buttons
|
// Bottom area
|
||||||
var flowButtons = new FlowLayoutPanel
|
var bottom = new TableLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
ColumnCount = 2,
|
||||||
|
RowCount = 1
|
||||||
|
};
|
||||||
|
bottom.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
|
||||||
|
bottom.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
|
||||||
|
|
||||||
|
var flowLeft = new FlowLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
FlowDirection = FlowDirection.LeftToRight,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
var btnParamCatalog = new Button { Text = "参数总表...", AutoSize = true };
|
||||||
|
btnParamCatalog.Click += (_, __) => OnOpenParamCatalog();
|
||||||
|
|
||||||
|
var btnTemplateBinding = new Button { Text = "模板参数绑定...", AutoSize = true };
|
||||||
|
btnTemplateBinding.Click += (_, __) => OnOpenTemplateBinding();
|
||||||
|
|
||||||
|
flowLeft.Controls.Add(btnParamCatalog);
|
||||||
|
flowLeft.Controls.Add(btnTemplateBinding);
|
||||||
|
|
||||||
|
var flowRight = new FlowLayoutPanel
|
||||||
{
|
{
|
||||||
Dock = DockStyle.Fill,
|
Dock = DockStyle.Fill,
|
||||||
FlowDirection = FlowDirection.RightToLeft,
|
FlowDirection = FlowDirection.RightToLeft,
|
||||||
@ -69,11 +93,14 @@ namespace CadParamPluging.UI
|
|||||||
var btnOk = new Button { Text = "确定" };
|
var btnOk = new Button { Text = "确定" };
|
||||||
btnOk.Click += (_, __) => OnOk();
|
btnOk.Click += (_, __) => OnOk();
|
||||||
|
|
||||||
flowButtons.Controls.Add(btnCancel);
|
flowRight.Controls.Add(btnCancel);
|
||||||
flowButtons.Controls.Add(btnOk);
|
flowRight.Controls.Add(btnOk);
|
||||||
|
|
||||||
|
bottom.Controls.Add(flowLeft, 0, 0);
|
||||||
|
bottom.Controls.Add(flowRight, 1, 0);
|
||||||
|
|
||||||
layout.Controls.Add(tabs, 0, 0);
|
layout.Controls.Add(tabs, 0, 0);
|
||||||
layout.Controls.Add(flowButtons, 0, 1);
|
layout.Controls.Add(bottom, 0, 1);
|
||||||
|
|
||||||
Controls.Add(layout);
|
Controls.Add(layout);
|
||||||
|
|
||||||
@ -81,6 +108,44 @@ namespace CadParamPluging.UI
|
|||||||
CancelButton = btnCancel;
|
CancelButton = btnCancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnOpenParamCatalog()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var catalog = ParamCatalogStore.Load();
|
||||||
|
using (var f = new ParamCatalogForm(catalog))
|
||||||
|
{
|
||||||
|
f.ShowDialog(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, $"打开参数总表失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOpenTemplateBinding()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var catalog = ParamCatalogStore.Load();
|
||||||
|
|
||||||
|
var projectTypes = _lbDeliveryStatuses.Items.Cast<object>().Select(o => (o as string) ?? string.Empty).ToList();
|
||||||
|
var drawingTypes = _lbProcessMethods.Items.Cast<object>().Select(o => (o as string) ?? string.Empty).ToList();
|
||||||
|
var sheetSizes = _lbStructuralFeatures.Items.Cast<object>().Select(o => (o as string) ?? string.Empty).ToList();
|
||||||
|
var scales = _lbSpecialConditions.Items.Cast<object>().Select(o => (o as string) ?? string.Empty).ToList();
|
||||||
|
|
||||||
|
using (var f = new TemplateSchemaBindingForm(projectTypes, drawingTypes, sheetSizes, scales, catalog))
|
||||||
|
{
|
||||||
|
f.ShowDialog(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, $"打开模板参数绑定失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void FillList(ListBox listBox, System.Collections.Generic.IEnumerable<string> items)
|
private static void FillList(ListBox listBox, System.Collections.Generic.IEnumerable<string> items)
|
||||||
{
|
{
|
||||||
listBox.Items.Clear();
|
listBox.Items.Clear();
|
||||||
|
|||||||
528
UI/TemplateSchemaBindingForm.cs
Normal file
528
UI/TemplateSchemaBindingForm.cs
Normal file
@ -0,0 +1,528 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using CadParamPluging.Common;
|
||||||
|
|
||||||
|
namespace CadParamPluging.UI
|
||||||
|
{
|
||||||
|
public class TemplateSchemaBindingForm : Form
|
||||||
|
{
|
||||||
|
private readonly ComboBox _cbProjectType;
|
||||||
|
private readonly ComboBox _cbDrawingType;
|
||||||
|
private readonly ComboBox _cbSheetSize;
|
||||||
|
private readonly ComboBox _cbScale;
|
||||||
|
private readonly TextBox _txtDisplayName;
|
||||||
|
private readonly Label _lblTemplateKey;
|
||||||
|
private readonly ListBox _lbSchemas;
|
||||||
|
private readonly ListView _lvParams;
|
||||||
|
|
||||||
|
private readonly ParamCatalog _catalog;
|
||||||
|
private TemplateSchemas _schemas;
|
||||||
|
|
||||||
|
public TemplateSchemaBindingForm(
|
||||||
|
System.Collections.Generic.IEnumerable<string> projectTypes,
|
||||||
|
System.Collections.Generic.IEnumerable<string> drawingTypes,
|
||||||
|
System.Collections.Generic.IEnumerable<string> sheetSizes,
|
||||||
|
System.Collections.Generic.IEnumerable<string> scales,
|
||||||
|
ParamCatalog catalog)
|
||||||
|
{
|
||||||
|
Text = "模板参数绑定";
|
||||||
|
Size = new Size(920, 620);
|
||||||
|
StartPosition = FormStartPosition.CenterParent;
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
ShowInTaskbar = false;
|
||||||
|
|
||||||
|
_catalog = (catalog ?? ParamCatalog.CreateDefault()).Clone();
|
||||||
|
_catalog.Normalize();
|
||||||
|
|
||||||
|
_schemas = TemplateSchemaStore.Load();
|
||||||
|
_schemas.Normalize();
|
||||||
|
|
||||||
|
var root = new TableLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
Padding = new Padding(10),
|
||||||
|
ColumnCount = 2,
|
||||||
|
RowCount = 2
|
||||||
|
};
|
||||||
|
root.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 260));
|
||||||
|
root.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
|
||||||
|
root.RowStyles.Add(new RowStyle(SizeType.Percent, 100f));
|
||||||
|
root.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||||
|
|
||||||
|
_lbSchemas = new ListBox { Dock = DockStyle.Fill };
|
||||||
|
_lbSchemas.SelectedIndexChanged += (_, __) => LoadSelectedSchemaToUi();
|
||||||
|
ReloadSchemaList();
|
||||||
|
|
||||||
|
var leftButtons = new FlowLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Bottom,
|
||||||
|
FlowDirection = FlowDirection.LeftToRight,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
var btnNew = new Button { Text = "新增模板", AutoSize = true };
|
||||||
|
btnNew.Click += (_, __) => OnNewSchema();
|
||||||
|
var btnDelete = new Button { Text = "删除模板", AutoSize = true };
|
||||||
|
btnDelete.Click += (_, __) => OnDeleteSchema();
|
||||||
|
leftButtons.Controls.Add(btnNew);
|
||||||
|
leftButtons.Controls.Add(btnDelete);
|
||||||
|
|
||||||
|
var leftPanel = new Panel { Dock = DockStyle.Fill };
|
||||||
|
leftPanel.Controls.Add(_lbSchemas);
|
||||||
|
leftPanel.Controls.Add(leftButtons);
|
||||||
|
leftButtons.Dock = DockStyle.Bottom;
|
||||||
|
|
||||||
|
var editor = new TableLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
ColumnCount = 2,
|
||||||
|
RowCount = 4,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
editor.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
|
||||||
|
editor.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
|
||||||
|
|
||||||
|
_cbProjectType = CreateCombo(projectTypes);
|
||||||
|
_cbDrawingType = CreateCombo(drawingTypes);
|
||||||
|
_cbSheetSize = CreateCombo(sheetSizes);
|
||||||
|
_cbScale = CreateCombo(scales);
|
||||||
|
|
||||||
|
_cbProjectType.SelectedIndexChanged += (_, __) => UpdateTemplateKeyLabel();
|
||||||
|
_cbDrawingType.SelectedIndexChanged += (_, __) => UpdateTemplateKeyLabel();
|
||||||
|
_cbSheetSize.SelectedIndexChanged += (_, __) => UpdateTemplateKeyLabel();
|
||||||
|
_cbScale.SelectedIndexChanged += (_, __) => UpdateTemplateKeyLabel();
|
||||||
|
|
||||||
|
_txtDisplayName = new TextBox { Width = 380 };
|
||||||
|
|
||||||
|
_lblTemplateKey = new Label { AutoSize = true, ForeColor = Color.DarkBlue };
|
||||||
|
|
||||||
|
var row = 0;
|
||||||
|
editor.Controls.Add(new Label { Text = "交付状态", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
editor.Controls.Add(_cbProjectType, 1, row++);
|
||||||
|
editor.Controls.Add(new Label { Text = "工艺方法", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
editor.Controls.Add(_cbDrawingType, 1, row++);
|
||||||
|
editor.Controls.Add(new Label { Text = "结构特征", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
editor.Controls.Add(_cbSheetSize, 1, row++);
|
||||||
|
editor.Controls.Add(new Label { Text = "特殊条件", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, row);
|
||||||
|
editor.Controls.Add(_cbScale, 1, row++);
|
||||||
|
|
||||||
|
var topBar = new TableLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Top,
|
||||||
|
ColumnCount = 2,
|
||||||
|
RowCount = 2,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
topBar.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
|
||||||
|
topBar.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
|
||||||
|
|
||||||
|
topBar.Controls.Add(new Label { Text = "显示名称", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, 0);
|
||||||
|
topBar.Controls.Add(_txtDisplayName, 1, 0);
|
||||||
|
topBar.Controls.Add(new Label { Text = "TemplateKey", AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }, 0, 1);
|
||||||
|
topBar.Controls.Add(_lblTemplateKey, 1, 1);
|
||||||
|
|
||||||
|
_lvParams = new ListView
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
View = View.Details,
|
||||||
|
FullRowSelect = true,
|
||||||
|
HideSelection = false,
|
||||||
|
CheckBoxes = true
|
||||||
|
};
|
||||||
|
_lvParams.Columns.Add("Label", 220);
|
||||||
|
_lvParams.Columns.Add("Key", 160);
|
||||||
|
|
||||||
|
var paramsButtonPanel = new FlowLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Top,
|
||||||
|
FlowDirection = FlowDirection.LeftToRight,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
var btnUp = new Button { Text = "上移", AutoSize = true };
|
||||||
|
btnUp.Click += (_, __) => MoveSelectedParam(-1);
|
||||||
|
var btnDown = new Button { Text = "下移", AutoSize = true };
|
||||||
|
btnDown.Click += (_, __) => MoveSelectedParam(1);
|
||||||
|
var btnSelectAll = new Button { Text = "全选", AutoSize = true };
|
||||||
|
btnSelectAll.Click += (_, __) => SetAllChecked(true);
|
||||||
|
var btnUnselectAll = new Button { Text = "全不选", AutoSize = true };
|
||||||
|
btnUnselectAll.Click += (_, __) => SetAllChecked(false);
|
||||||
|
paramsButtonPanel.Controls.Add(btnUp);
|
||||||
|
paramsButtonPanel.Controls.Add(btnDown);
|
||||||
|
paramsButtonPanel.Controls.Add(btnSelectAll);
|
||||||
|
paramsButtonPanel.Controls.Add(btnUnselectAll);
|
||||||
|
|
||||||
|
var rightPanel = new TableLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
ColumnCount = 1,
|
||||||
|
RowCount = 3
|
||||||
|
};
|
||||||
|
rightPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||||
|
rightPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||||
|
rightPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f));
|
||||||
|
|
||||||
|
rightPanel.Controls.Add(editor, 0, 0);
|
||||||
|
rightPanel.Controls.Add(topBar, 0, 1);
|
||||||
|
|
||||||
|
var paramArea = new TableLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
ColumnCount = 1,
|
||||||
|
RowCount = 2
|
||||||
|
};
|
||||||
|
paramArea.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||||
|
paramArea.RowStyles.Add(new RowStyle(SizeType.Percent, 100f));
|
||||||
|
paramArea.Controls.Add(paramsButtonPanel, 0, 0);
|
||||||
|
paramArea.Controls.Add(_lvParams, 0, 1);
|
||||||
|
|
||||||
|
rightPanel.Controls.Add(paramArea, 0, 2);
|
||||||
|
|
||||||
|
var bottomButtons = new FlowLayoutPanel
|
||||||
|
{
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
FlowDirection = FlowDirection.RightToLeft,
|
||||||
|
AutoSize = true
|
||||||
|
};
|
||||||
|
var btnClose = new Button { Text = "关闭", DialogResult = DialogResult.Cancel };
|
||||||
|
var btnSave = new Button { Text = "保存" };
|
||||||
|
btnSave.Click += (_, __) => OnSave();
|
||||||
|
bottomButtons.Controls.Add(btnClose);
|
||||||
|
bottomButtons.Controls.Add(btnSave);
|
||||||
|
|
||||||
|
root.Controls.Add(leftPanel, 0, 0);
|
||||||
|
root.Controls.Add(rightPanel, 1, 0);
|
||||||
|
root.Controls.Add(bottomButtons, 0, 1);
|
||||||
|
root.SetColumnSpan(bottomButtons, 2);
|
||||||
|
|
||||||
|
Controls.Add(root);
|
||||||
|
CancelButton = btnClose;
|
||||||
|
|
||||||
|
BuildParamListItems();
|
||||||
|
UpdateTemplateKeyLabel();
|
||||||
|
if (_lbSchemas.Items.Count > 0)
|
||||||
|
{
|
||||||
|
_lbSchemas.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ComboBox CreateCombo(System.Collections.Generic.IEnumerable<string> items)
|
||||||
|
{
|
||||||
|
var cb = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Width = 220 };
|
||||||
|
var arr = (items ?? Enumerable.Empty<string>())
|
||||||
|
.Where(s => !string.IsNullOrWhiteSpace(s))
|
||||||
|
.Select(s => s.Trim())
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToArray();
|
||||||
|
if (arr.Length > 0)
|
||||||
|
{
|
||||||
|
cb.Items.AddRange(arr);
|
||||||
|
cb.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
return cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildParamListItems()
|
||||||
|
{
|
||||||
|
_lvParams.BeginUpdate();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_lvParams.Items.Clear();
|
||||||
|
foreach (var p in (_catalog.Items ?? Enumerable.Empty<ParamDefinition>()).OrderBy(x => x.Order))
|
||||||
|
{
|
||||||
|
var it = new ListViewItem(new[] { p.Label, p.Key })
|
||||||
|
{
|
||||||
|
Tag = p.Key,
|
||||||
|
Checked = false
|
||||||
|
};
|
||||||
|
_lvParams.Items.Add(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lvParams.EndUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplySchemaToParamList(TemplateSchemaDefinition schema)
|
||||||
|
{
|
||||||
|
var selectedKeys = (schema?.SelectedParamKeys ?? new List<string>()).ToList();
|
||||||
|
var keySet = new HashSet<string>(selectedKeys, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
var all = _lvParams.Items.Cast<ListViewItem>().ToList();
|
||||||
|
var byKey = all.ToDictionary(i => (string)i.Tag, i => i, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
var ordered = new List<ListViewItem>();
|
||||||
|
foreach (var k in selectedKeys)
|
||||||
|
{
|
||||||
|
if (byKey.TryGetValue(k, out var it))
|
||||||
|
{
|
||||||
|
ordered.Add(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var it in all)
|
||||||
|
{
|
||||||
|
if (!keySet.Contains((string)it.Tag))
|
||||||
|
{
|
||||||
|
ordered.Add(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_lvParams.BeginUpdate();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_lvParams.Items.Clear();
|
||||||
|
foreach (var it in ordered)
|
||||||
|
{
|
||||||
|
var key = (string)it.Tag;
|
||||||
|
it.Checked = keySet.Contains(key);
|
||||||
|
_lvParams.Items.Add(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lvParams.EndUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReloadSchemaList()
|
||||||
|
{
|
||||||
|
var prev = _lbSchemas.SelectedIndex;
|
||||||
|
|
||||||
|
_lbSchemas.Items.Clear();
|
||||||
|
foreach (var s in (_schemas.Items ?? Enumerable.Empty<TemplateSchemaDefinition>())
|
||||||
|
.OrderBy(x => x.ProjectType)
|
||||||
|
.ThenBy(x => x.DrawingType)
|
||||||
|
.ThenBy(x => x.SheetSize)
|
||||||
|
.ThenBy(x => x.Scale))
|
||||||
|
{
|
||||||
|
_lbSchemas.Items.Add(FormatSchema(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lbSchemas.Items.Count > 0)
|
||||||
|
{
|
||||||
|
_lbSchemas.SelectedIndex = Math.Max(0, Math.Min(prev, _lbSchemas.Items.Count - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatSchema(TemplateSchemaDefinition s)
|
||||||
|
{
|
||||||
|
if (s == null)
|
||||||
|
{
|
||||||
|
return "(null)";
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = string.IsNullOrWhiteSpace(s.DisplayName) ? "(未命名)" : s.DisplayName;
|
||||||
|
return $"{name} | {s.ProjectType}/{s.DrawingType}/{s.SheetSize}/{s.Scale}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private TemplateSchemaDefinition GetSelectedSchema()
|
||||||
|
{
|
||||||
|
var idx = _lbSchemas.SelectedIndex;
|
||||||
|
if (idx < 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ordered = (_schemas.Items ?? Enumerable.Empty<TemplateSchemaDefinition>())
|
||||||
|
.OrderBy(x => x.ProjectType)
|
||||||
|
.ThenBy(x => x.DrawingType)
|
||||||
|
.ThenBy(x => x.SheetSize)
|
||||||
|
.ThenBy(x => x.Scale)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (idx >= ordered.Count)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = ordered[idx].TemplateKey;
|
||||||
|
return (_schemas.Items ?? new List<TemplateSchemaDefinition>()).FirstOrDefault(x => string.Equals(x.TemplateKey, key, StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSelectedSchemaToUi()
|
||||||
|
{
|
||||||
|
var schema = GetSelectedSchema();
|
||||||
|
if (schema == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectComboByText(_cbProjectType, schema.ProjectType);
|
||||||
|
SelectComboByText(_cbDrawingType, schema.DrawingType);
|
||||||
|
SelectComboByText(_cbSheetSize, schema.SheetSize);
|
||||||
|
SelectComboByText(_cbScale, schema.Scale);
|
||||||
|
_txtDisplayName.Text = schema.DisplayName ?? string.Empty;
|
||||||
|
UpdateTemplateKeyLabel();
|
||||||
|
ApplySchemaToParamList(schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SelectComboByText(ComboBox cb, string value)
|
||||||
|
{
|
||||||
|
if (cb == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var v = (value ?? string.Empty).Trim();
|
||||||
|
for (var i = 0; i < cb.Items.Count; i++)
|
||||||
|
{
|
||||||
|
if (string.Equals((cb.Items[i] as string) ?? string.Empty, v, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
cb.SelectedIndex = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTemplateKeyLabel()
|
||||||
|
{
|
||||||
|
var key = TemplateKeyBuilder.Build(_cbProjectType.Text, _cbDrawingType.Text, _cbSheetSize.Text, _cbScale.Text);
|
||||||
|
_lblTemplateKey.Text = key ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnNewSchema()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(_cbProjectType.Text) || string.IsNullOrWhiteSpace(_cbDrawingType.Text))
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, "请先选择模板四个参数。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var candidate = new TemplateSchemaDefinition
|
||||||
|
{
|
||||||
|
ProjectType = _cbProjectType.Text,
|
||||||
|
DrawingType = _cbDrawingType.Text,
|
||||||
|
SheetSize = _cbSheetSize.Text,
|
||||||
|
Scale = _cbScale.Text,
|
||||||
|
DisplayName = _txtDisplayName.Text
|
||||||
|
};
|
||||||
|
candidate.Normalize();
|
||||||
|
|
||||||
|
if ((_schemas.Items ?? new List<TemplateSchemaDefinition>()).Any(x => string.Equals(x.TemplateKey, candidate.TemplateKey, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, "该模板定义已存在(四参数组合重复)。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_schemas.Items == null)
|
||||||
|
{
|
||||||
|
_schemas.Items = new List<TemplateSchemaDefinition>();
|
||||||
|
}
|
||||||
|
_schemas.Items.Add(candidate);
|
||||||
|
_schemas.Normalize();
|
||||||
|
ReloadSchemaList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDeleteSchema()
|
||||||
|
{
|
||||||
|
var schema = GetSelectedSchema();
|
||||||
|
if (schema == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, "请先选择一个模板定义。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var confirm = MessageBox.Show(this, $"确认删除模板定义:{FormatSchema(schema)}?", "删除", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
|
||||||
|
if (confirm != DialogResult.Yes)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_schemas.Items = (_schemas.Items ?? Enumerable.Empty<TemplateSchemaDefinition>())
|
||||||
|
.Where(x => !string.Equals(x.TemplateKey, schema.TemplateKey, StringComparison.OrdinalIgnoreCase))
|
||||||
|
.ToList();
|
||||||
|
_schemas.Normalize();
|
||||||
|
ReloadSchemaList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveSelectedParam(int delta)
|
||||||
|
{
|
||||||
|
if (_lvParams.SelectedItems.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = _lvParams.SelectedItems[0];
|
||||||
|
var idx = item.Index;
|
||||||
|
var newIdx = idx + delta;
|
||||||
|
if (newIdx < 0 || newIdx >= _lvParams.Items.Count)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lvParams.BeginUpdate();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_lvParams.Items.RemoveAt(idx);
|
||||||
|
_lvParams.Items.Insert(newIdx, item);
|
||||||
|
item.Selected = true;
|
||||||
|
item.Focused = true;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lvParams.EndUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetAllChecked(bool value)
|
||||||
|
{
|
||||||
|
_lvParams.BeginUpdate();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (ListViewItem it in _lvParams.Items)
|
||||||
|
{
|
||||||
|
it.Checked = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lvParams.EndUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSave()
|
||||||
|
{
|
||||||
|
var schema = GetSelectedSchema();
|
||||||
|
if (schema == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, "请先选择一个模板定义。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
schema.ProjectType = _cbProjectType.Text;
|
||||||
|
schema.DrawingType = _cbDrawingType.Text;
|
||||||
|
schema.SheetSize = _cbSheetSize.Text;
|
||||||
|
schema.Scale = _cbScale.Text;
|
||||||
|
schema.DisplayName = _txtDisplayName.Text;
|
||||||
|
schema.SelectedParamKeys = _lvParams.Items
|
||||||
|
.Cast<ListViewItem>()
|
||||||
|
.Where(i => i.Checked)
|
||||||
|
.Select(i => (string)i.Tag)
|
||||||
|
.ToList();
|
||||||
|
schema.Normalize();
|
||||||
|
|
||||||
|
if ((_schemas.Items ?? new List<TemplateSchemaDefinition>())
|
||||||
|
.Any(x => !ReferenceEquals(x, schema) && string.Equals(x.TemplateKey, schema.TemplateKey, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, "保存失败:存在重复的四参数组合。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TemplateSchemaStore.Save(_schemas);
|
||||||
|
MessageBox.Show(this, "已保存。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
ReloadSchemaList();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show(this, $"保存失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user