如何获取DataGridView选中复选框行索引并分配计算序列?
DataGridView选中行捕获与计算序列分配解决方案
问题背景
我有一个DataGridView控件,前几列为数据列,最右侧最后一列为复选框列。控件限制仅能同时选中2行作为输入数据,当选中行的数据发生变更时,其余行需根据输入行的数据计算更新。总共有6行,任意两行组合均可被选中,目前需要解决的是如何捕获选中的2行,并为其分配对应的计算序列。
现有代码框架:
private void dgvParameters_CellValueChanged(object sender, DataGridViewCellEventArgs e) { //Get index of Rows with boxes checked in Column [5] and assign an integer array sequence //Ex: if Rows 1 & 3 are selected then int sequence = new int[6] {0,5,2,4,6}; //Ex: if Rows 1 & 2 are selected then int sequence = new int[2] {0,3,7}; for (int i = 0; i < sequence.Length; i++) { switch (sequence[i]) { case 0: //Do calculation for input from row 0 to update other rows break; case 1: //Do calculation for input from row 1 to update other rows break; ... case 7: //Do calculation for input from row 7 to update other rows default: break; } } }
公式与计算序列规则:
//Formulas f() for calculation data values: Row 1 = a = f(c,d) Row 2 = b = f(a,d) Row 3 = c = f(a,b) Row 4 = d = f(b,c) //EX: if Row 1 & 2 selected then use the values in these cells to solve for Row 3 & 4 //sequences have to be in a particular order to update the formulas correctly. if Rows Selected = 1 & 2 then sequence = {3 ,4} //Calculate Rows 3 & 4 if Rows Selected = 3 & 4 then sequence = {1, 2} if Rows Selected = 1 & 4 then sequence = {2, 3}
实现步骤与代码
1. 捕获选中行并限制选中数量
添加辅助方法获取选中的行索引,同时确保最多选中2行:
private List<int> GetSelectedRowIndices() { List<int> selectedIndices = new List<int>(); foreach (DataGridViewRow row in dgvParameters.Rows) { // 检查复选框列(索引5)的选中状态,避免空值异常 if (row.Cells[5].Value != null && (bool)row.Cells[5].Value) { selectedIndices.Add(row.Index); } } // 限制仅能选中2行,超出时自动取消多余选中 if (selectedIndices.Count > 2) { // 临时禁用事件避免重复触发 dgvParameters.CellValueChanged -= dgvParameters_CellValueChanged; for (int i = 2; i < selectedIndices.Count; i++) { dgvParameters.Rows[selectedIndices[i]].Cells[5].Value = false; } dgvParameters.CellValueChanged += dgvParameters_CellValueChanged; // 保留前2个选中行 selectedIndices = selectedIndices.Take(2).ToList(); } return selectedIndices; }
2. 定义计算序列映射字典
在窗体初始化时创建映射,将选中行组合与对应的计算序列关联,注意对选中行索引排序,避免顺序差异导致匹配失败:
private Dictionary<string, int[]> _calculationSequenceMap; private void InitializeSequenceMap() { _calculationSequenceMap = new Dictionary<string, int[]>(); // 按选中行索引升序拼接作为键,确保1&2和2&1匹配同一序列 _calculationSequenceMap.Add("1,2", new int[] { 3, 4 }); _calculationSequenceMap.Add("3,4", new int[] { 1, 2 }); _calculationSequenceMap.Add("1,4", new int[] { 2, 3 }); // 补充其他所有可能的2行组合对应的序列,例如: // _calculationSequenceMap.Add("0,1", new int[] { ... }); // _calculationSequenceMap.Add("0,2", new int[] { ... }); // ... 其余组合 }
3. 修改CellValueChanged事件逻辑
更新事件方法,完成选中行捕获、序列匹配与计算执行:
private void dgvParameters_CellValueChanged(object sender, DataGridViewCellEventArgs e) { // 仅处理数据列或复选框列的变更 if (e.ColumnIndex < 5 || e.ColumnIndex == 5) { List<int> selectedRows = GetSelectedRowIndices(); // 选中行数量不为2时不执行计算 if (selectedRows.Count != 2) return; // 排序选中行索引,生成字典匹配键 selectedRows.Sort(); string key = string.Join(",", selectedRows); // 获取对应计算序列并执行计算 if (_calculationSequenceMap.TryGetValue(key, out int[] sequence)) { foreach (int rowIndex in sequence) { switch (rowIndex) { case 1: // 执行Row1的计算逻辑:a = f(c,d) break; case 2: // 执行Row2的计算逻辑:b = f(a,d) break; case 3: // 执行Row3的计算逻辑:c = f(a,b) break; case 4: // 执行Row4的计算逻辑:d = f(b,c) break; // 补充其他行的计算逻辑 } } } } }
4. 初始化映射字典
在窗体加载事件中调用初始化方法:
private void Form_Load(object sender, EventArgs e) { InitializeSequenceMap(); }
内容的提问来源于stack exchange,提问作者user2040536
相关产品推荐
相关产品推荐

