using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms; using CadParamPluging.Common; namespace CadParamPluging.UI { public class SettingsForm : Form { private sealed class EditableOptionItem { public string Category { get; set; } public string RawValue { get; set; } public string DisplayName { get; set; } public bool IsBuiltIn { get; set; } public override string ToString() { return DisplayName; } } private readonly ListBox _lbDeliveryStatuses; private readonly ListBox _lbProcessMethods; private readonly ListBox _lbStructuralFeatures; private readonly ListBox _lbSpecialConditions; private readonly DropdownOptions _workingOptions; private readonly DropdownOptions _builtInDefaults; public DropdownOptions Result { get; private set; } public SettingsForm(DropdownOptions current) { Text = "设置"; Size = new Size(600, 500); StartPosition = FormStartPosition.CenterScreen; FormBorderStyle = FormBorderStyle.FixedDialog; MaximizeBox = false; MinimizeBox = false; ShowInTaskbar = false; Font = SystemFonts.MessageBoxFont; _workingOptions = (current ?? DropdownOptions.CreateDefault()).Clone(); _workingOptions.Normalize(); _builtInDefaults = DropdownOptions.CreateDefault(); _builtInDefaults.Normalize(); var mainLayout = new TableLayoutPanel { Dock = DockStyle.Fill, Padding = new Padding(12), RowCount = 2, ColumnCount = 1 }; mainLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); _lbDeliveryStatuses = new ListBox(); _lbProcessMethods = new ListBox(); _lbStructuralFeatures = new ListBox(); _lbSpecialConditions = new ListBox(); RefreshList(_lbDeliveryStatuses, DropdownOptionCategory.DeliveryStatus); RefreshList(_lbProcessMethods, DropdownOptionCategory.ProcessMethod); RefreshList(_lbStructuralFeatures, DropdownOptionCategory.StructuralFeature); RefreshList(_lbSpecialConditions, DropdownOptionCategory.SpecialCondition); var tabs = new TabControl { Dock = DockStyle.Fill }; tabs.TabPages.Add(BuildEditableTab("交付状态", _lbDeliveryStatuses)); tabs.TabPages.Add(BuildEditableTab("工艺方法", _lbProcessMethods)); tabs.TabPages.Add(BuildEditableTab("结构特征", _lbStructuralFeatures)); tabs.TabPages.Add(BuildEditableTab("特殊条件", _lbSpecialConditions)); var bottomGrid = new TableLayoutPanel { Dock = DockStyle.Fill, RowCount = 1, ColumnCount = 2, AutoSize = true, Margin = new Padding(0, 8, 0, 0) }; bottomGrid.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); bottomGrid.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); var leftTools = new FlowLayoutPanel { Dock = DockStyle.Fill, AutoSize = true, FlowDirection = FlowDirection.LeftToRight }; var btnParamCatalog = new Button { Text = "参数总表", AutoSize = true }; btnParamCatalog.Click += (_, __) => OnOpenParamCatalog(); var btnTemplateBinding = new Button { Text = "模板绑定", AutoSize = true }; btnTemplateBinding.Click += (_, __) => OnOpenTemplateBinding(); leftTools.Controls.Add(btnParamCatalog); leftTools.Controls.Add(btnTemplateBinding); var rightActions = new FlowLayoutPanel { Dock = DockStyle.Fill, AutoSize = true, FlowDirection = FlowDirection.RightToLeft }; var btnCancel = new Button { Text = "取消", DialogResult = DialogResult.Cancel, Width = 80 }; var btnOk = new Button { Text = "确定", Width = 80 }; btnOk.Click += (_, __) => OnOk(); rightActions.Controls.Add(btnCancel); rightActions.Controls.Add(btnOk); bottomGrid.Controls.Add(leftTools, 0, 0); bottomGrid.Controls.Add(rightActions, 1, 0); mainLayout.Controls.Add(tabs, 0, 0); mainLayout.Controls.Add(bottomGrid, 0, 1); Controls.Add(mainLayout); AcceptButton = btnOk; 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(); using (var f = new TemplateSchemaBindingForm(_workingOptions.Clone(), catalog)) { f.ShowDialog(this); } } catch (Exception ex) { MessageBox.Show(this, "打开模板参数绑定失败:\n\n" + ex, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private TabPage BuildEditableTab(string title, ListBox listBox) { var page = new TabPage(title); page.Padding = new Padding(8); page.UseVisualStyleBackColor = true; var layout = new TableLayoutPanel { Dock = DockStyle.Fill, ColumnCount = 2, RowCount = 1, }; layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); layout.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 100f)); listBox.Dock = DockStyle.Fill; listBox.IntegralHeight = false; var actions = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.TopDown, WrapContents = false, Padding = new Padding(4, 0, 0, 0) }; var btnAdd = new Button { Text = "新增", Width = 90, Height = 30 }; btnAdd.Click += (_, __) => OnAddItem(title, listBox); var btnEdit = new Button { Text = "修改", Width = 90, Height = 30 }; btnEdit.Click += (_, __) => OnEditItem(title, listBox); var btnDelete = new Button { Text = "删除", Width = 90, Height = 30 }; btnDelete.Click += (_, __) => OnDeleteItem(title, listBox); actions.Controls.Add(btnAdd); actions.Controls.Add(btnEdit); actions.Controls.Add(btnDelete); layout.Controls.Add(listBox, 0, 0); layout.Controls.Add(actions, 1, 0); page.Controls.Add(layout); return page; } private void OnAddItem(string categoryTitle, ListBox listBox) { var category = GetCategoryKey(categoryTitle); if (!TextInputForm.TryGetValue(this, categoryTitle + " - 新增", "请输入内容:", string.Empty, out var value)) { return; } value = (value ?? string.Empty).Trim(); if (value.Length == 0) { MessageBox.Show(this, "内容不能为空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } var list = GetOptionList(category); if (list.Any(x => string.Equals(x, value, StringComparison.OrdinalIgnoreCase))) { MessageBox.Show(this, "该项已存在。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } list.Add(value); RefreshList(listBox, category, value); } private void OnEditItem(string categoryTitle, ListBox listBox) { var item = listBox.SelectedItem as EditableOptionItem; if (item == null || string.IsNullOrWhiteSpace(item.RawValue)) { MessageBox.Show(this, "请先选择一项再修改。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } var prompt = item.IsBuiltIn ? "请输入显示名称:" : "请输入内容:"; if (!TextInputForm.TryGetValue(this, categoryTitle + " - 修改", prompt, item.DisplayName, out var value)) { return; } value = (value ?? string.Empty).Trim(); if (value.Length == 0) { MessageBox.Show(this, "内容不能为空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } if (item.IsBuiltIn) { _workingOptions.SetDisplayNameOverride(item.Category, item.RawValue, value); RefreshList(listBox, item.Category, item.RawValue); return; } var list = GetOptionList(item.Category); var duplicate = list.Any(x => !string.Equals(x, item.RawValue, StringComparison.OrdinalIgnoreCase) && string.Equals(x, value, StringComparison.OrdinalIgnoreCase)); if (duplicate) { MessageBox.Show(this, "该项已存在。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } var idx = list.FindIndex(x => string.Equals(x, item.RawValue, StringComparison.OrdinalIgnoreCase)); if (idx < 0) { return; } _workingOptions.SetDisplayNameOverride(item.Category, item.RawValue, item.RawValue); list[idx] = value; RefreshList(listBox, item.Category, value); } private void OnDeleteItem(string categoryTitle, ListBox listBox) { var item = listBox.SelectedItem as EditableOptionItem; if (item == null || string.IsNullOrWhiteSpace(item.RawValue)) { MessageBox.Show(this, "请先选择一项再删除。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (item.IsBuiltIn) { MessageBox.Show(this, "内置项不建议删除。如需换名字,请使用【修改】。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } var confirm = MessageBox.Show( this, "确认删除:" + item.DisplayName + "?", categoryTitle + " - 删除", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (confirm != DialogResult.Yes) { return; } var list = GetOptionList(item.Category); list.RemoveAll(x => string.Equals(x, item.RawValue, StringComparison.OrdinalIgnoreCase)); _workingOptions.SetDisplayNameOverride(item.Category, item.RawValue, item.RawValue); RefreshList(listBox, item.Category, null); } private void OnOk() { var result = _workingOptions.Clone(); result.Normalize(); var err = ValidateResult(result); if (err != null) { MessageBox.Show(this, err, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } Result = result; DialogResult = DialogResult.OK; Close(); } private void RefreshList(ListBox listBox, string category, string preferredRawValue = null) { listBox.Items.Clear(); foreach (var rawValue in GetOptionList(category)) { listBox.Items.Add(new EditableOptionItem { Category = category, RawValue = rawValue, DisplayName = _workingOptions.GetDisplayName(category, rawValue), IsBuiltIn = GetBuiltInValues(category).Any(x => string.Equals(x, rawValue, StringComparison.OrdinalIgnoreCase)) }); } if (listBox.Items.Count == 0) { return; } if (!string.IsNullOrWhiteSpace(preferredRawValue)) { for (var i = 0; i < listBox.Items.Count; i++) { var item = listBox.Items[i] as EditableOptionItem; if (item != null && string.Equals(item.RawValue, preferredRawValue, StringComparison.OrdinalIgnoreCase)) { listBox.SelectedIndex = i; return; } } } listBox.SelectedIndex = 0; } private List GetOptionList(string category) { switch (category) { case DropdownOptionCategory.DeliveryStatus: return _workingOptions.DeliveryStatuses; case DropdownOptionCategory.ProcessMethod: return _workingOptions.ProcessMethods; case DropdownOptionCategory.StructuralFeature: return _workingOptions.StructuralFeatures; case DropdownOptionCategory.SpecialCondition: return _workingOptions.SpecialConditions; default: return new List(); } } private List GetBuiltInValues(string category) { switch (category) { case DropdownOptionCategory.DeliveryStatus: return _builtInDefaults.DeliveryStatuses; case DropdownOptionCategory.ProcessMethod: return _builtInDefaults.ProcessMethods; case DropdownOptionCategory.StructuralFeature: return _builtInDefaults.StructuralFeatures; case DropdownOptionCategory.SpecialCondition: return _builtInDefaults.SpecialConditions; default: return new List(); } } private static string GetCategoryKey(string title) { switch (title) { case "交付状态": return DropdownOptionCategory.DeliveryStatus; case "工艺方法": return DropdownOptionCategory.ProcessMethod; case "结构特征": return DropdownOptionCategory.StructuralFeature; case "特殊条件": return DropdownOptionCategory.SpecialCondition; default: return string.Empty; } } private static string ValidateResult(DropdownOptions options) { if (options.DeliveryStatuses == null || options.DeliveryStatuses.Count == 0) { return "交付状态至少需要 1 项。"; } if (options.ProcessMethods == null || options.ProcessMethods.Count == 0) { return "工艺方法至少需要 1 项。"; } if (options.StructuralFeatures == null || options.StructuralFeatures.Count == 0) { return "结构特征至少需要 1 项。"; } if (options.SpecialConditions == null || options.SpecialConditions.Count == 0) { return "特殊条件至少需要 1 项。"; } return null; } } }