302 lines
10 KiB
C#
302 lines
10 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
}
|