529 lines
19 KiB
C#
529 lines
19 KiB
C#
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);
|
||
}
|
||
}
|
||
}
|
||
}
|