求助:实现DataGridView中各彩票号码的出现次数统计功能
彩票号码出现次数统计功能完善
问题说明
我有一个加载了彩票号码列表的DataGridView,需要统计表格中每个号码的出现次数。目前编写的代码仅能统计单个号码的出现次数,现需完善实现批量统计所有号码的功能。
现有代码
当前统计方法代码
private void calculaTotalGrid() { ResultadoNumeros numer = new ResultadoNumeros(); int badCount = dgLista.Rows.Cast<DataGridViewRow>().Where(row => row.Cells[2].Value.ToString() == "01").Count(); lbl_01.Text = badCount.ToString(); } int val; int valToCount = 10; int count = 0; foreach (var row in dgLista.Rows.Cast<DataGridViewRow>()) foreach (var cell in row.Cells.Cast<DataGridViewCell>()) count += int.TryParse(cell.Value?.ToString(), out val) && val == valToCount ? 1 : 0; txtNum.Text = count.ToString();
ResultadoNumeros类定义
public int concurso { get; set; } public int _01 { get; set; } ---- public int _15 { get; set; }
数据库数据获取方法
public static DataTable ObterNumeros() { DataTable tabela = new DataTable(); DALConexao conexao = new DALConexao(DadosDaConexao.StringDaConexao); SqlCommand cmd = new SqlCommand(); cmd.Connection = conexao.ObjetConexao; SqlDataAdapter da = new SqlDataAdapter("Select * from TBLotofacil ORDER BY Concurso DESC", conexao.StringConexao); da.Fill(tabela); return tabela; } }
完善后的实现方案
基础版本:手动赋值统计结果
private void calculaTotalGrid() { // 初始化字典,存储1-15号的出现次数,初始值为0 Dictionary<int, int> numberCounts = new Dictionary<int, int>(); for (int i = 1; i <= 15; i++) { numberCounts[i] = 0; } // 遍历DataGridView所有行和单元格统计次数 foreach (DataGridViewRow row in dgLista.Rows) { // 跳过新行(若允许用户添加空白行) if (row.IsNewRow) continue; foreach (DataGridViewCell cell in row.Cells) { // 尝试解析单元格值为有效号码(1-15),成功则更新计数 if (int.TryParse(cell.Value?.ToString(), out int number) && number >= 1 && number <= 15) { numberCounts[number]++; } } } // 将统计结果赋值给ResultadoNumeros对象 ResultadoNumeros numer = new ResultadoNumeros(); numer._01 = numberCounts[1]; numer._02 = numberCounts[2]; numer._03 = numberCounts[3]; numer._04 = numberCounts[4]; numer._05 = numberCounts[5]; numer._06 = numberCounts[6]; numer._07 = numberCounts[7]; numer._08 = numberCounts[8]; numer._09 = numberCounts[9]; numer._10 = numberCounts[10]; numer._11 = numberCounts[11]; numer._12 = numberCounts[12]; numer._13 = numberCounts[13]; numer._14 = numberCounts[14]; numer._15 = numberCounts[15]; // 更新对应Label的显示文本 lbl_01.Text = numer._01.ToString(); lbl_02.Text = numer._02.ToString(); lbl_03.Text = numer._03.ToString(); lbl_04.Text = numer._04.ToString(); lbl_05.Text = numer._05.ToString(); lbl_06.Text = numer._06.ToString(); lbl_07.Text = numer._07.ToString(); lbl_08.Text = numer._08.ToString(); lbl_09.Text = numer._09.ToString(); lbl_10.Text = numer._10.ToString(); lbl_11.Text = numer._11.ToString(); lbl_12.Text = numer._12.ToString(); lbl_13.Text = numer._13.ToString(); lbl_14.Text = numer._14.ToString(); lbl_15.Text = numer._15.ToString(); }
优化版本:用反射简化赋值操作
如果不想手动编写15次赋值代码,可以用反射自动匹配属性和控件:
private void calculaTotalGrid() { Dictionary<int, int> numberCounts = new Dictionary<int, int>(); for (int i = 1; i <= 15; i++) { numberCounts[i] = 0; } foreach (DataGridViewRow row in dgLista.Rows) { if (row.IsNewRow) continue; foreach (DataGridViewCell cell in row.Cells) { if (int.TryParse(cell.Value?.ToString(), out int number) && number >=1 && number <=15) { numberCounts[number]++; } } } // 自动赋值ResultadoNumeros的属性 ResultadoNumeros numer = new ResultadoNumeros(); foreach (var kvp in numberCounts) { // 生成属性名,如_01、_02 string propertyName = $"_{kvp.Key:D2}"; System.Reflection.PropertyInfo prop = typeof(ResultadoNumeros).GetProperty(propertyName); prop?.SetValue(numer, kvp.Value); } // 自动更新对应Label foreach (var kvp in numberCounts) { // 生成Label名称,如lbl_01、lbl_02 string labelName = $"lbl_{kvp.Key:D2}"; Label targetLabel = Controls.Find(labelName, true).FirstOrDefault() as Label; targetLabel?.Text = kvp.Value.ToString(); } }
说明
- 使用
Dictionary<int, int>统一管理所有号码的统计结果,避免重复编写单个号码的统计逻辑 - 遍历单元格时增加了有效号码范围判断,防止无效值干扰统计
- 反射版本通过命名规则自动匹配属性和Label,减少冗余代码,后期号码范围变更时只需调整循环边界即可
内容的提问来源于stack exchange,提问作者Edilson Lemos
相关产品推荐
相关产品推荐

