using LB_SmartVision.Forms.Pages.ProcessPage; using LB_SmartVision.ProcessRun; using LB_VisionControl; using LB_VisionProcesses; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System.Collections.Concurrent; using System.Data; using System.Text; using VisionControl.Forms; namespace LB_SmartVision.Forms.Pages.SettingPage { public partial class SettingEditPage : UserControl { public Action LogInfo; RunSettingPage RunSettingPage = new RunSettingPage(); LayoutPage LayoutPage = new LayoutPage(); CsvPage CsvPage = new CsvPage(); public SettingEditPage() { Name = "SettingEditPage"; Text = "流程设置"; //this.Font = new Font("Microsoft YaHei UI", 16F, FontStyle.Regular, GraphicsUnit.Point, 0); InitializeComponent(); dataGridView.DataError += new DataGridViewDataErrorEventHandler(dataGridView_DataError); pageSetting.Controls.Add(RunSettingPage); RunSettingPage.Dock = DockStyle.Fill; pageLayout.Controls.Add(LayoutPage); LayoutPage.Dock = DockStyle.Fill; pageCsv.Controls.Add(CsvPage); CsvPage.Dock = DockStyle.Fill; } private void SettingEditPage_Paint(object sender, PaintEventArgs e) { RunSettingPage.LoadFromJson(); uiFlowLayoutPanel1.Controls.Clear(); if (GlobalVar.dicProcesses.Count <= 0) return; // 使用方式 var sortedKeys = GlobalVar.dicProcesses.Keys .OrderBy(k => k, new NaturalStringComparer()) .ToList(); foreach (var key in sortedKeys) { string ProcessesName = key; string ProcessesOK = GlobalVar.dicProcesses[ProcessesName].Rate_OK.ToString() + "%"; if (string.IsNullOrEmpty(ProcessesName) || string.IsNullOrEmpty(ProcessesOK)) return; UserItem flow = new UserItem(new string[] { "重命名", "移除" }); flow.Name = ProcessesName; flow.Text = $"[{ProcessesOK}]"; if (GlobalVar.dicProcesses[ProcessesName].Result) flow.state = State.Pass; else flow.state = State.Error; LoadFlowEvent(flow); uiFlowLayoutPanel1.Controls.Add(flow); } LoadData(); } private void btn_AddProcess_Click(object sender, EventArgs e) { string Name = "流程" + GlobalVar.dicProcesses.Count; while (GlobalVar.dicProcesses.ContainsKey(Name)) Name += "副本"; if (string.IsNullOrEmpty(Name)) return; int hashCode = GlobalVar.dicProcesses.GetHashCode(); GlobalVar.dicProcesses.TryAdd(Name, new ProcessRunBll(Name, GlobalVar.dicCameras, GlobalVar.dicCommunicators)); LogInfo?.Invoke(string.Format("添加流程[{0}]成功", Name), LogInfoType.PASS); this.Invalidate(); } private void LoadFlowEvent(UserItem flow) { //按键1为重命名 flow.MenuItem1ClickedEvent += RenameEvent; //按键2为移除 flow.MenuItem2ClickedEvent += DeleteEvent; } private void RemoveFlowEvent(UserItem flow) { //按键1为重命名 flow.MenuItem1ClickedEvent -= RenameEvent; //按键2为移除 flow.MenuItem2ClickedEvent -= DeleteEvent; } /// /// 重命名流程 /// /// /// private void RenameEvent(string Name, string Text) { RenameForm renameForm = new RenameForm(Name); // 订阅事件 renameForm.ShowDialog(); if (!renameForm.bRename) return; if (GlobalVar.dicProcesses.ContainsKey(renameForm.strNewName)) { MessageBox.Show("命名重复!", "异常"); return; } for (int i = 0; i < uiFlowLayoutPanel1.Controls.Count; i++) { UserItem flow = (UserItem)uiFlowLayoutPanel1.Controls[i]; string name = flow.Name; if (name != Name) continue; flow.Name = renameForm.strNewName; string oldName = name; string newName = renameForm.strNewName; // 重命名前保存流程 if (GlobalVar.dicProcesses.ContainsKey(oldName) && GlobalVar.dicProcesses[oldName].Save(out _)) GlobalVar.dicProcesses.TryRename(oldName, newName); flow.Refresh(); } } /// /// 移除流程 /// /// /// private void DeleteEvent(string Name, string Text) { if (uiFlowLayoutPanel1.Controls.Count <= 1) { MessageBox.Show("至少保留一个流程"); return; } try { this.BeginInvoke(new Action(() => { for (int i = 0; i < uiFlowLayoutPanel1.Controls.Count; i++) { UserItem flow = (UserItem)uiFlowLayoutPanel1.Controls[i]; string name = flow.Name; if (name != Name) continue; // 执行额外的逻辑,如确认删除或记录数据 DialogResult result = MessageBox.Show($"确定要删除[{name}]?该操作是不可恢复的", "删除确认", MessageBoxButtons.YesNoCancel); // 如果用户选择“否”,则取消删除操作 if (result == DialogResult.Yes) { RemoveFlowEvent(flow); uiFlowLayoutPanel1.Controls.Remove(uiFlowLayoutPanel1.Controls[i]); GlobalVar.dicProcesses.TryRemove(name, out ProcessRunBll ProcessRunBll); string ProcessPath = GlobalVar.allProcessPath + name; if (Directory.Exists(ProcessPath)) Directory.Delete(ProcessPath, true); } } })); } catch { } } private void LoadData() { dataGridView.AllowUserToAddRows = false; dataGridView.Columns.Clear(); dataGridView.Rows.Clear(); dataGridView.DataSource = null; // 创建带有 ComboBox 的列 DataGridViewComboBoxColumn comboBoxColumn0 = new DataGridViewComboBoxColumn(); comboBoxColumn0.HeaderText = "流程名"; comboBoxColumn0.Name = "TableName"; comboBoxColumn0.Items.Add("无"); foreach (var ProcessName in GlobalVar.dicProcesses.Keys) comboBoxColumn0.Items.Add(ProcessName); dataGridView.Columns.Add(comboBoxColumn0); // 创建带有 ComboBox 的列 DataGridViewComboBoxColumn comboBoxColumn1 = new DataGridViewComboBoxColumn(); comboBoxColumn1.HeaderText = "触发通讯"; comboBoxColumn1.Name = "TriggerComName"; comboBoxColumn1.Items.Add("无"); foreach (var ComName in GlobalVar.dicCommunicators.Keys) comboBoxColumn1.Items.Add(ComName); dataGridView.Columns.Add(comboBoxColumn1); // 创建普通文本列 dataGridView.Columns.Add("TriggerString", "触发字符"); DataGridViewComboBoxColumn comboBoxColumn2 = new DataGridViewComboBoxColumn(); comboBoxColumn2.HeaderText = "成功通讯"; comboBoxColumn2.Name = "PassComName"; comboBoxColumn2.Items.Add("无"); foreach (var ComName in GlobalVar.dicCommunicators.Keys) comboBoxColumn2.Items.Add(ComName); dataGridView.Columns.Add(comboBoxColumn2); // 创建普通文本列 dataGridView.Columns.Add("PassString", "成功字符"); DataGridViewComboBoxColumn comboBoxColumn3 = new DataGridViewComboBoxColumn(); comboBoxColumn3.HeaderText = "失败通讯"; comboBoxColumn3.Name = "ErrorComName"; comboBoxColumn3.Items.Add("无"); foreach (var ComName in GlobalVar.dicCommunicators.Keys) comboBoxColumn3.Items.Add(ComName); dataGridView.Columns.Add(comboBoxColumn3); dataGridView.Columns.Add("ErrorString", "失败字符"); // 创建普通文本列 dataGridView.Columns.Add("RetestTimes", "重测次数"); dataGridView.Columns.Add("ConnectProcess", "关联流程"); // 创建带有 Button 的列 DataGridViewButtonColumn btnEditResult = new DataGridViewButtonColumn(); btnEditResult.HeaderText = "关联结果"; btnEditResult.Name = "ConnectResult"; btnEditResult.Text = "未关联"; // 按钮显示的文本 btnEditResult.UseColumnTextForButtonValue = false; // 禁用统一文本 dataGridView.Columns.Add(btnEditResult); foreach (var item in GlobalVar.dicProcessSetting.OrderBy(kvp => kvp.Key)) { string ProcessName = item.Value["流程名"]; string TriggerComName = item.Value["触发通讯"]; string TriggerString = item.Value["触发字符"]; string PassComName = item.Value["成功通讯"]; string PassString = item.Value["成功字符"]; string ErrorComName = item.Value["失败通讯"]; string ErrorString = item.Value["失败字符"]; string RetestTimes = item.Value["重测次数"]; string ConnectProcess = item.Value["关联流程"]; string ConnectResult = item.Value["关联结果"]; if (string.IsNullOrEmpty(ConnectResult) || ConnectResult.Trim() == "") ConnectResult = "未关联"; if (!GlobalVar.dicCommunicators.ContainsKey(TriggerComName) && GlobalVar.dicCommunicators.Count > 0) { if (TriggerComName != "无") TriggerComName = GlobalVar.dicCommunicators.ElementAt(0).Key; item.Value["触发通讯"] = TriggerComName; } if (!GlobalVar.dicCommunicators.ContainsKey(PassComName) && GlobalVar.dicCommunicators.Count > 0) { if (PassComName != "无") PassComName = GlobalVar.dicCommunicators.ElementAt(0).Key; item.Value["成功通讯"] = PassComName; } if (!GlobalVar.dicCommunicators.ContainsKey(ErrorComName) && GlobalVar.dicCommunicators.Count > 0) { if (ErrorComName != "无") ErrorComName = GlobalVar.dicCommunicators.ElementAt(0).Key; item.Value["失败通讯"] = ErrorComName; } // 添加行并设置按钮文本 int rowIndex = dataGridView.Rows.Add( ProcessName, TriggerComName, TriggerString, PassComName, PassString, ErrorComName, ErrorString, RetestTimes, ConnectProcess ); // 单独设置按钮列的值为ConnectRsult dataGridView.Rows[rowIndex].Cells["ConnectResult"].Value = ConnectResult; } //dataGridView.Columns["DBName"].ReadOnly = true; } private void dataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e) { // 记录错误但不显示默认对话框 e.ThrowException = false; //// 可以自定义错误处理 //MessageBox.Show($"数据错误: {e.Exception.Message}", "错误", // MessageBoxButtons.OK, MessageBoxIcon.Error); //// 或者简单地忽略错误 //e.Cancel = true; } private void dataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) { int rowIndex = e.RowIndex; // 获取修改的行索引 int columnIndex = e.ColumnIndex; // 获取修改的列索引 if (e.ColumnIndex == 0 && dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex] != null && dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewComboBoxCell) { DataGridViewComboBoxCell cell = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewComboBoxCell; // 清空原有选项 cell.Items.Clear(); foreach (var ProcessName in GlobalVar.dicProcesses.Keys) cell.Items.Add(ProcessName); } if ((e.ColumnIndex == 1 || e.ColumnIndex == 3) && dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex] != null && dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewComboBoxCell) { DataGridViewComboBoxCell cell = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewComboBoxCell; // 清空原有选项 cell.Items.Clear(); cell.Items.Add("无"); foreach (var ComName in GlobalVar.dicCommunicators.Keys) cell.Items.Add(ComName); } } private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) { int rowIndex = e.RowIndex; // 获取修改的行索引 int columnIndex = e.ColumnIndex; // 获取修改的列索引 } private void dataGridView_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e) { // 获取当前即将被删除的行的数据 DataGridViewRow rowToDelete = e.Row; // 假设我们要检查第一列的数据 string ProcessName = rowToDelete.Cells[0]?.Value?.ToString(); // 执行额外的逻辑,如确认删除或记录数据 DialogResult result = MessageBox.Show($"确定要删除?该操作是不可恢复的", "删除确认", MessageBoxButtons.YesNo); // 如果用户选择“否”,则取消删除操作 if (result == DialogResult.No) { e.Cancel = true; // 取消删除操作 } else { LogInfo?.Invoke(string.Format("流程[{0}]删除触发设置", ProcessName), LogInfoType.INFO); // 如果需要,可以在这里执行删除前的额外处理 GlobalVar.dicProcessSetting.TryRemove(e.Row.Index, out ConcurrentDictionary dic); } } private void dataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e) { try { if (e.ColumnIndex == dataGridView.Columns["ConnectResult"].Index && e.RowIndex >= 0) { // 获取当前行的数据 string ProcessName = dataGridView.Rows[e.RowIndex].Cells["TableName"].Value?.ToString(); if (string.IsNullOrEmpty(ProcessName)) return; ProcessOutputsSelectForm processOutputsSelectForm = new ProcessOutputsSelectForm(GlobalVar.dicProcesses[ProcessName].dicInputsMapping, GlobalVar.dicProcesses[ProcessName].dicOutputsMapping); processOutputsSelectForm.ShowDialog(); if (string.IsNullOrEmpty(processOutputsSelectForm.SelectedOutput)) { (GlobalVar.dicProcessSetting[e.RowIndex])["关联结果"] = processOutputsSelectForm.SelectedOutput; dataGridView.Rows[e.RowIndex].Cells["ConnectResult"].Value = processOutputsSelectForm.SelectedOutput; } } } catch { } } private void btn_SaveProcessSetting_Click(object sender, EventArgs e) { GlobalVar.dicProcessSetting.Clear(); foreach (DataGridViewRow row in dataGridView.Rows) { if (!row.IsNewRow && row.Cells.Count >= 3 && row.Cells[0].Value != null) { ConcurrentDictionary keyValuePairs = new ConcurrentDictionary(); int i = 0; i = 0; string ProcessName = row.Cells[i].Value == null ? "" : row.Cells[i].Value.ToString(); i = 1; string TriggerComName = row.Cells[i].Value == null ? "" : row.Cells[i].Value.ToString(); i = 2; string TriggerString = row.Cells[i].Value == null ? "" : row.Cells[i].Value.ToString(); i = 3; string PassComName = row.Cells[i].Value == null ? "" : row.Cells[i].Value.ToString(); i = 4; string PassString = row.Cells[i].Value == null ? "" : row.Cells[i].Value.ToString(); i = 5; string ErrorComName = row.Cells[i].Value == null ? "" : row.Cells[i].Value.ToString(); i = 6; string ErrorString = row.Cells[i].Value == null ? "" : row.Cells[i].Value.ToString(); i = 7; string RetestTimes = row.Cells[i].Value == null ? "" : row.Cells[i].Value.ToString(); i = 8; string ConnectProcess = row.Cells[i].Value == null ? "" : row.Cells[i].Value.ToString(); i = 9; string ConnectResult = row.Cells[i].Value == null ? "未关联" : row.Cells[i].Value.ToString(); keyValuePairs.TryAdd("流程名", ProcessName); keyValuePairs.TryAdd("触发通讯", TriggerComName); keyValuePairs.TryAdd("触发字符", TriggerString); keyValuePairs.TryAdd("成功通讯", PassComName); keyValuePairs.TryAdd("成功字符", PassString); keyValuePairs.TryAdd("失败通讯", ErrorComName); keyValuePairs.TryAdd("失败字符", ErrorString); keyValuePairs.TryAdd("重测次数", RetestTimes); keyValuePairs.TryAdd("关联流程", ConnectProcess); keyValuePairs.TryAdd("关联结果", ConnectResult); GlobalVar.dicProcessSetting.TryAdd(row.Index, keyValuePairs); } } if (!VisionForm.SaveAllProcessSetting()) { MessageBox.Show("保存失败!", "异常"); LogInfo?.Invoke(string.Format("保存流程失败"), LogInfoType.ERROR); } else LogInfo?.Invoke(string.Format("保存流程成功"), LogInfoType.PASS); } private void btn_Add_Click(object sender, EventArgs e) { string ProcessName = string.Empty; if (GlobalVar.dicProcesses.Count > 0) ProcessName = GlobalVar.dicProcesses.Keys.ToList()[0]; ConcurrentDictionary keyValuePairs = new ConcurrentDictionary(); string ComName = string.Empty; if (string.IsNullOrEmpty(ComName) && GlobalVar.dicCommunicators.Count > 0) ComName = GlobalVar.dicCommunicators.ElementAt(0).Key; keyValuePairs.TryAdd("流程名", ProcessName); keyValuePairs.TryAdd("触发通讯", ComName); keyValuePairs.TryAdd("触发字符", "TEST"); keyValuePairs.TryAdd("成功通讯", ComName); keyValuePairs.TryAdd("成功字符", "WB_OK"); keyValuePairs.TryAdd("失败通讯", ComName); keyValuePairs.TryAdd("失败字符", "WB_NG"); keyValuePairs.TryAdd("重测次数", "0"); keyValuePairs.TryAdd("关联流程", ""); keyValuePairs.TryAdd("关联结果", "未关联"); GlobalVar.dicProcessSetting.TryAdd(dataGridView.Rows.Count, keyValuePairs); LogInfo?.Invoke(string.Format("流程[{0}]新建触发设置", ProcessName), LogInfoType.INFO); LoadData(); } } }