|
|
@@ -0,0 +1,385 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.ComponentModel;
|
|
|
+using System.Data;
|
|
|
+using System.Drawing;
|
|
|
+using System.Linq;
|
|
|
+using System.Security.Policy;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using System.Windows.Forms;
|
|
|
+
|
|
|
+namespace OTSIncAReportApp._1_UI.OTSReportExport
|
|
|
+{
|
|
|
+ public partial class GroupSelector : Form
|
|
|
+ {
|
|
|
+ // 原始数据源
|
|
|
+ private DataTable dtGroups; // 分组表:GroupId, GroupName, inoId, display
|
|
|
+ private List<DataTable> listRuleTable; // 每个分组的条目表:StrName, display
|
|
|
+
|
|
|
+ //输出结果
|
|
|
+ public DataTable GroupSelectionInformation { get; set; }//每个组是否别选中
|
|
|
+ public List<DataTable> ResultTables { get; set; } // 每个分组的条目表:StrName, display
|
|
|
+ public bool IsConfirmed { get; private set; } = false; // 是否点击了确认按钮
|
|
|
+
|
|
|
+ // 运行时状态
|
|
|
+ private Dictionary<int, Dictionary<string, bool>> itemStates; // GroupId -> (条目名称 -> 是否选中)
|
|
|
+ private Dictionary<int, List<string>> groupItems; // GroupId -> 该分组的所有条目名称列表
|
|
|
+ private Dictionary<int, string> groupNames; // GroupId -> GroupName
|
|
|
+
|
|
|
+
|
|
|
+ private bool isLoading = false; // 防止事件循环
|
|
|
+ private bool isSelectAllChanging = false; // 防止全选状态改变时的事件循环
|
|
|
+
|
|
|
+ public GroupSelector(DataTable groups, List<DataTable> ruleTables)
|
|
|
+ {
|
|
|
+ dtGroups = groups;
|
|
|
+ listRuleTable = ruleTables;
|
|
|
+ InitializeComponent();
|
|
|
+ LoadData();
|
|
|
+ RegisterEvents();
|
|
|
+ GroupSelectionInformation = new DataTable();
|
|
|
+ GroupSelectionInformation = groups.Clone();
|
|
|
+ ResultTables = new List<DataTable>();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 加载数据并初始化界面
|
|
|
+ private void LoadData()
|
|
|
+ {
|
|
|
+ if (dtGroups == null || listRuleTable == null)
|
|
|
+ throw new ArgumentNullException("数据源不能为空");
|
|
|
+
|
|
|
+ itemStates = new Dictionary<int, Dictionary<string, bool>>();
|
|
|
+ groupItems = new Dictionary<int, List<string>>();
|
|
|
+ groupNames = new Dictionary<int, string>();
|
|
|
+
|
|
|
+ // 先建立 GroupId 到条目表的映射(假设 listRuleTable 的顺序与 dtGroups 相同,但为安全起见按 GroupId 匹配)
|
|
|
+ // 由于 List_RuleTable 没有直接存储 GroupId,这里假定顺序一致且数量相等
|
|
|
+ if (dtGroups.Rows.Count != listRuleTable.Count)
|
|
|
+ MessageBox.Show("警告:分组数量与条目表数量不一致,将按顺序匹配,请确保数据正确。", "数据不一致", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
+
|
|
|
+ for (int i = 0; i < dtGroups.Rows.Count; i++)
|
|
|
+ {
|
|
|
+ DataRow row = dtGroups.Rows[i];
|
|
|
+ int groupId = Convert.ToInt32(row["GroupId"]);
|
|
|
+ string groupName = row["GroupName"].ToString();
|
|
|
+ groupNames[groupId] = groupName;
|
|
|
+
|
|
|
+ // 获取对应的条目表
|
|
|
+ DataTable itemTable = listRuleTable[i];
|
|
|
+ List<string> items = new List<string>();
|
|
|
+ Dictionary<string, bool> states = new Dictionary<string, bool>();
|
|
|
+
|
|
|
+ foreach (DataRow itemRow in itemTable.Rows)
|
|
|
+ {
|
|
|
+ string strName = itemRow["StrName"].ToString();
|
|
|
+ bool display = false;
|
|
|
+ if (itemRow["display"].ToString() == "1")
|
|
|
+ {
|
|
|
+ display = true;
|
|
|
+ }
|
|
|
+ //bool display = Convert.ToBoolean(itemRow["display"]);
|
|
|
+ items.Add(strName);
|
|
|
+ states[strName] = display;
|
|
|
+ }
|
|
|
+
|
|
|
+ groupItems[groupId] = items;
|
|
|
+ itemStates[groupId] = states;
|
|
|
+
|
|
|
+ // 左侧添加分组(显示 GroupName,使用 GroupId 作为 Tag 以便获取)
|
|
|
+ int index = clbGroups.Items.Add(groupName);
|
|
|
+
|
|
|
+ if (row["display"].ToString() == "1")
|
|
|
+ {
|
|
|
+ clbGroups.SetItemChecked(index, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 默认选中第一个分组
|
|
|
+ //if (clbGroups.Items.Count > 0)
|
|
|
+ // clbGroups.SelectedIndex = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 注册事件
|
|
|
+ private void RegisterEvents()
|
|
|
+ {
|
|
|
+ clbGroups.SelectedIndexChanged += ClbGroups_SelectedIndexChanged;
|
|
|
+ clbItems.ItemCheck += ClbItems_ItemCheck;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 左侧分组切换时,加载对应分组的条目及勾选状态
|
|
|
+ private void ClbGroups_SelectedIndexChanged(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ if (isLoading) return;
|
|
|
+ if (clbGroups.SelectedIndex < 0) return;
|
|
|
+
|
|
|
+ // 获取当前选中的 GroupId
|
|
|
+ int groupId = GetCurrentGroupId();
|
|
|
+ if (!groupItems.ContainsKey(groupId)) return;
|
|
|
+
|
|
|
+ isLoading = true;
|
|
|
+
|
|
|
+ // 清空右侧并加载当前分组的条目
|
|
|
+ clbItems.Items.Clear();
|
|
|
+ foreach (string item in groupItems[groupId])
|
|
|
+ {
|
|
|
+ bool isChecked = itemStates[groupId][item];
|
|
|
+ clbItems.Items.Add(item, isChecked);
|
|
|
+ }
|
|
|
+
|
|
|
+ isLoading = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 右侧条目勾选状态改变时,更新当前分组的选中状态字典
|
|
|
+ private void ClbItems_ItemCheck(object sender, ItemCheckEventArgs e)
|
|
|
+ {
|
|
|
+ if (isLoading) return;
|
|
|
+ if (clbGroups.SelectedIndex < 0) return;
|
|
|
+
|
|
|
+ int groupId = GetCurrentGroupId();
|
|
|
+ string itemName = clbItems.Items[e.Index].ToString();
|
|
|
+
|
|
|
+ bool newChecked = (e.NewValue == CheckState.Checked);
|
|
|
+ itemStates[groupId][itemName] = newChecked;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取当前选中分组的 GroupId(通过选中索引对应 dtGroups 中的行)
|
|
|
+ private int GetCurrentGroupId()
|
|
|
+ {
|
|
|
+ int selectedIndex = clbGroups.SelectedIndex;
|
|
|
+ if (selectedIndex >= 0 && selectedIndex < dtGroups.Rows.Count)
|
|
|
+ return Convert.ToInt32(dtGroups.Rows[selectedIndex]["GroupId"]);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void clbGroups_SelectedIndexChanged_1(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ if (isLoading) return;
|
|
|
+ if (clbGroups.SelectedIndex < 0) return;
|
|
|
+
|
|
|
+ int groupIndex = clbGroups.SelectedIndex;
|
|
|
+ if (!groupItems.ContainsKey(groupIndex)) return;
|
|
|
+
|
|
|
+ isLoading = true;
|
|
|
+
|
|
|
+ // 清空右侧并加载当前分组的条目
|
|
|
+ clbItems.Items.Clear();
|
|
|
+ foreach (string item in groupItems[groupIndex])
|
|
|
+ {
|
|
|
+ bool isChecked = itemStates[groupIndex][item];
|
|
|
+ clbItems.Items.Add(item, isChecked);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新全选 CheckBox 状态
|
|
|
+ UpdateSelectAllCheckBox();
|
|
|
+
|
|
|
+ isLoading = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据当前右侧列表的实际勾选情况,更新全选 CheckBox 的三态状态
|
|
|
+ private void UpdateSelectAllCheckBox()
|
|
|
+ {
|
|
|
+ if (clbItems.Items.Count == 0)
|
|
|
+ {
|
|
|
+ chkSelectAll.CheckState = CheckState.Unchecked;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int checkedCount = 0;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ for (int i = 0; i < clbItems.Items.Count; i++)
|
|
|
+ {
|
|
|
+ if (clbItems.GetItemChecked(i))
|
|
|
+ checkedCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (checkedCount == 0)
|
|
|
+ chkSelectAll.CheckState = CheckState.Unchecked;
|
|
|
+ else if (checkedCount == clbItems.Items.Count)
|
|
|
+ chkSelectAll.CheckState = CheckState.Checked;
|
|
|
+ else
|
|
|
+ chkSelectAll.CheckState = CheckState.Indeterminate;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void clbItems_ItemCheck_1(object sender, ItemCheckEventArgs e)
|
|
|
+ {
|
|
|
+ if (isLoading) return;
|
|
|
+ if (clbGroups.SelectedIndex < 0) return;
|
|
|
+
|
|
|
+
|
|
|
+ isSelectAllChanging = true;
|
|
|
+ int groupIndex = clbGroups.SelectedIndex;
|
|
|
+ string itemName = clbItems.Items[e.Index].ToString();
|
|
|
+
|
|
|
+ // 注意:ItemCheck 事件中无法直接获取新的勾选状态(e.NewValue),
|
|
|
+ // 但我们需要先更新字典,稍后刷新 CheckBox 状态时使用更新后的值。
|
|
|
+ // 为了避免直接修改字典导致后续更新不一致,这里暂不修改,在事件结束后统一处理。
|
|
|
+ // 更好的方法:延迟更新,但为了简单,我们在事件中临时计算新状态。
|
|
|
+ // 由于 CheckBox 状态同步需要知道更新后的字典,这里先更新字典(根据新值)。
|
|
|
+ bool newChecked = (e.NewValue == CheckState.Checked);
|
|
|
+ itemStates[groupIndex][itemName] = newChecked;
|
|
|
+
|
|
|
+ // 由于 ItemCheck 事件执行时,CheckedListBox 的勾选视觉尚未更新,
|
|
|
+ // 但我们的字典已经更新,接下来需要刷新全选 CheckBox 状态。
|
|
|
+ // 使用 BeginInvoke 延迟执行,确保界面更新完成后再同步 CheckBox 状态。
|
|
|
+ this.BeginInvoke(new Action(() => UpdateSelectAllCheckBox()));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void chkSelectAll_ClientSizeChanged(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void btnConfirm_Click(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ GroupSelectionInformation=new DataTable();
|
|
|
+ GroupSelectionInformation = dtGroups.Clone();
|
|
|
+ ResultTables = new List<DataTable>();
|
|
|
+ for (int i = 0; i < dtGroups.Rows.Count; i++)
|
|
|
+ {
|
|
|
+ GroupSelectionInformation.Rows.Add(dtGroups.Rows[i].ItemArray);
|
|
|
+
|
|
|
+ DataTable dataTable = listRuleTable[i].Copy();
|
|
|
+ int GroupId = Convert.ToInt32(dtGroups.Rows[i]["GroupId"]);
|
|
|
+ DataTable dt= new DataTable();
|
|
|
+ dt.Columns.Add("StrName", typeof(string));
|
|
|
+ dt.Columns.Add("display", typeof(int));
|
|
|
+ // 按照原始顺序添加所有条目,并设置最新的 display 状态
|
|
|
+ foreach (string itemName in groupItems[GroupId])
|
|
|
+ {
|
|
|
+ bool isChecked = itemStates[GroupId][itemName];
|
|
|
+ DataRow dr = dt.NewRow();
|
|
|
+ dr["StrName"] = itemName;
|
|
|
+ if (isChecked)
|
|
|
+ dr["display"] = 1;
|
|
|
+ else
|
|
|
+ dr["display"] = 0;
|
|
|
+ dt.Rows.Add(dr);
|
|
|
+ }
|
|
|
+ for (int a = 0; a < dataTable.Rows.Count; a++)
|
|
|
+ {
|
|
|
+ for (int j = 0; j < dt.Rows.Count; j++)
|
|
|
+ {
|
|
|
+ if (dataTable.Rows[a]["StrName"].ToString() == dt.Rows[j]["StrName"].ToString())
|
|
|
+ {
|
|
|
+ dataTable.Rows[a]["display"] = dt.Rows[j]["display"].ToString();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ResultTables.Add(dataTable);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < clbGroups.Items.Count; i++)
|
|
|
+ {
|
|
|
+ if (clbGroups.GetItemChecked(i))
|
|
|
+ {
|
|
|
+ GroupSelectionInformation.Rows[i]["display"] = "1";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ GroupSelectionInformation.Rows[i]["display"] = "0";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IsConfirmed= true;
|
|
|
+ this.Close();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void chkSelectAll_CheckStateChanged(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ if (!isSelectAllChanging)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < clbItems.Items.Count; i++)
|
|
|
+ {
|
|
|
+ clbItems.SetItemChecked(i, chkSelectAll.Checked);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ isSelectAllChanging = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void GroupSelector_Load(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ // 清空右侧并加载当前分组的条目
|
|
|
+ //clbItems.Items.Clear();
|
|
|
+
|
|
|
+ // 默认选中第一个分组
|
|
|
+ if (clbGroups.Items.Count > 0)
|
|
|
+ clbGroups.SelectedIndex = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateAllGroupsSelectAllCheckBox()
|
|
|
+ {
|
|
|
+ if (groupItems.Count == 0)
|
|
|
+ {
|
|
|
+ chkSelectAllAllGroups.CheckState = CheckState.Unchecked;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int totalItems = 0;
|
|
|
+ int totalChecked = 0;
|
|
|
+ foreach (var kvp in itemStates)
|
|
|
+ {
|
|
|
+ var states = kvp.Value;
|
|
|
+ totalItems += states.Count;
|
|
|
+ foreach (var itemState in states)
|
|
|
+ {
|
|
|
+ if (itemState.Value) totalChecked++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (totalChecked == 0)
|
|
|
+ chkSelectAllAllGroups.CheckState = CheckState.Unchecked;
|
|
|
+ else if (totalChecked == totalItems)
|
|
|
+ chkSelectAllAllGroups.CheckState = CheckState.Checked;
|
|
|
+ else
|
|
|
+ chkSelectAllAllGroups.CheckState = CheckState.Indeterminate;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void chkSelectAllAllGroups_CheckStateChanged(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ if (isLoading) return;
|
|
|
+ bool shouldCheckAll = (chkSelectAllAllGroups.CheckState == CheckState.Checked);
|
|
|
+
|
|
|
+ isLoading = true;
|
|
|
+
|
|
|
+ // 更新所有分组的条目状态
|
|
|
+ foreach (var groupIndex in groupItems.Keys)
|
|
|
+ {
|
|
|
+ var items = groupItems[groupIndex];
|
|
|
+ foreach (string itemName in items)
|
|
|
+ {
|
|
|
+ itemStates[groupIndex][itemName] = shouldCheckAll;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 刷新当前显示的右侧列表界面
|
|
|
+ int currentGroup = clbGroups.SelectedIndex;
|
|
|
+ if (currentGroup >= 0 && groupItems.ContainsKey(currentGroup))
|
|
|
+ {
|
|
|
+ for (int i = 0; i < clbItems.Items.Count; i++)
|
|
|
+ {
|
|
|
+ string itemName = clbItems.Items[i].ToString();
|
|
|
+ clbItems.SetItemChecked(i, shouldCheckAll);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新右侧全选 CheckBox 的状态
|
|
|
+ UpdateSelectAllCheckBox();
|
|
|
+ for (int i = 0; i < clbGroups.Items.Count; i++)
|
|
|
+ {
|
|
|
+ clbGroups.SetItemChecked(i, chkSelectAllAllGroups.Checked);
|
|
|
+ }
|
|
|
+ isLoading = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void button1_Click(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ this.Close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|