如何在Form1中获取Form2的DataGridView单元格计数结果
解决方案:从Form2传递数字计数结果到Form1
以下是几种可行的实现方式,按耦合度从低到高排序:
方法1:通过公开字典属性传递(推荐)
利用Form2中已有的ResultadoNumeros字典,将其改为公开属性,让Form1直接读取结果。
步骤1:修改Form2的字典定义
在Form2类中,将ResultadoNumeros改为公开只读属性:
// 替换原有私有定义,改为公开只读属性 public Dictionary<int, int> ResultadoNumeros { get; private set; } = new Dictionary<int, int>();
步骤2:优化计算逻辑避免报错
修改calculaTotalGrid方法,添加键存在判断,防止数字未出现时抛出异常:
public void calculaTotalGrid() { int outVal = 0; ResultadoNumeros = dgResultadoGeral.Rows.Cast<DataGridViewRow>() .SelectMany(r => r.Cells.Cast<DataGridViewCell>() .Where(c => c.ColumnIndex > 0 && int.TryParse(c.Value?.ToString(), out outVal))) .GroupBy(c => int.Parse(c.Value.ToString())) .ToDictionary(x => x.Key, x => x.Count()); // 用TryGetValue安全获取计数,未出现则显示0 if (ResultadoNumeros.TryGetValue(1, out int count1)) lbl_01.Text = count1.ToString(); else lbl_01.Text = "0"; // ... 02到25的数字处理逻辑同理,全部替换为TryGetValue方式 if (ResultadoNumeros.TryGetValue(25, out int count25)) lbl_25.Text = count25.ToString(); else lbl_25.Text = "0"; }
步骤3:在Form1中读取结果
当Form2完成计算后,在Form1中直接访问其字典属性更新控件:
// 在Form1中打开Form2的示例代码 var form2 = new Form2(); form2.ShowDialog(); // 模态窗口确保计算完成后再读取结果 // 遍历字典更新Form1的对应Label foreach (var kvp in form2.ResultadoNumeros) { // 按数字格式拼接控件名称(如数字1对应lbl_01) var targetLabel = this.Controls.Find($"lbl_{kvp.Key:D2}", true).FirstOrDefault() as Label; if (targetLabel != null) { targetLabel.Text = kvp.Value.ToString(); } } // 补全未出现在字典中的数字,显示0 for (int num = 1; num <=25; num++) { if (!form2.ResultadoNumeros.ContainsKey(num)) { var targetLabel = this.Controls.Find($"lbl_{num:D2}", true).FirstOrDefault() as Label; if (targetLabel != null) { targetLabel.Text = "0"; } } }
方法2:通过事件回调传递(解耦最优)
定义事件让Form2在计算完成后主动通知Form1,完全解耦两个窗体的依赖关系。
步骤1:在Form2中定义事件
// 在Form2类中添加事件定义 public event Action<Dictionary<int, int>> OnNumerosCalculados;
步骤2:计算完成后触发事件
修改calculaTotalGrid方法,在逻辑末尾触发事件:
public void calculaTotalGrid() { // ... 原有计算逻辑不变 // 计算完成后触发事件,传递结果字典 OnNumerosCalculados?.Invoke(ResultadoNumeros); }
步骤3:在Form1中订阅事件
var form2 = new Form2(); // 订阅事件,接收计算结果并更新Form1控件 form2.OnNumerosCalculados += (resultados) => { // 更新Label逻辑同方法1 foreach (var kvp in resultados) { var targetLabel = this.Controls.Find($"lbl_{kvp.Key:D2}", true).FirstOrDefault() as Label; if (targetLabel != null) { targetLabel.Text = kvp.Value.ToString(); } } // 补全未出现数字的0值 for (int num = 1; num <=25; num++) { if (!resultados.ContainsKey(num)) { var targetLabel = this.Controls.Find($"lbl_{num:D2}", true).FirstOrDefault() as Label; if (targetLabel != null) { targetLabel.Text = "0"; } } } }; form2.Show();
方法3:直接引用Form1控件(不推荐)
这种方式耦合度极高,仅适合临时测试场景:
// 在Form2的calculaTotalGrid方法中,直接查找Form1实例更新控件 var form1 = Application.OpenForms.OfType<Form1>().FirstOrDefault(); if (form1 != null) { if (ResultadoNumeros.TryGetValue(1, out int count1)) { var label = form1.Controls.Find($"lbl_01", true).FirstOrDefault() as Label; if (label != null) label.Text = count1.ToString(); } // ... 其他数字同理 }
内容的提问来源于stack exchange,提问作者Edilson Lemos
相关产品推荐
相关产品推荐

