C# WinForm DataGridView卖家销量排序及层级统计问题求解
核心问题根因定位
1. 多位数销量排序失效原因
当前手动往DataGridView单元格写入的是销量的字符串形式,DataGridView默认对字符串类型内容采用字典序排序:
- 个位数场景下,单字符的字典序和数值顺序一致,所以结果看起来正确
- 10及以上的多位数场景下,会出现
"10" < "2"的字典序比较结果,完全不符合数值排序预期
2. 等级计数永远显示1的原因
- 等级统计逻辑中实例化了一个无数据的空
Salesman对象,读取的是int类型默认值0,完全没有匹配已录入的真实卖家数据 - 计数逻辑没有遍历所有已录入的卖家行,每次仅对这个空对象做一次判断,从0开始仅累加1,无论实际录入多少卖家都只会返回1
- 录入逻辑中每次都在按钮点击事件里新建局部DataTable,没有统一的全局数据源,数据无法被统一读取、统计
分步修改方案
1. 初始化全局强类型数据源
将DataTable提升为Form类的全局成员,定义列时明确指定数据类型,从根源上解决类型不匹配的问题,同时把表格直接绑定到数据源,无需手动操作单元格:
public partial class Form1 : Form { // 全局统一的卖家数据源 private DataTable _salesmanTable; public Form1() { InitializeComponent(); // 初始化全局表结构 _salesmanTable = new DataTable(); _salesmanTable.Columns.Add("Namn", typeof(string)); _salesmanTable.Columns.Add("Personnummer", typeof(string)); _salesmanTable.Columns.Add("Distrikt", typeof(string)); // 关键:销量列指定为整数类型,匹配数值排序的要求 _salesmanTable.Columns.Add("Antal artiklar", typeof(int)); // 绑定数据源到DataGridView,自动同步数据 dataGridView1.DataSource = _salesmanTable; } }
2. 改造卖家录入逻辑
移除原有事件里临时新建DataTable、手动塞单元格的冗余逻辑,直接往全局数据源追加行,绑定机制会自动刷新表格显示:
private void button1_Click(object sender, EventArgs e) { // 保留原有文本框取值逻辑 string name = txtName.Text.Trim(); string securityNumber = txtSecurity.Text.Trim(); string district = txtDistrict.Text.Trim(); int amountSold = int.Parse(txtAmount.Text.Trim()); // 往全局表追加新行 DataRow newRow = _salesmanTable.NewRow(); newRow["Namn"] = name; newRow["Personnummer"] = securityNumber; newRow["Distrikt"] = district; newRow["Antal artiklar"] = amountSold; _salesmanTable.Rows.Add(newRow); // 保留原有清空文本框逻辑 txtName.Clear(); txtSecurity.Clear(); txtDistrict.Clear(); txtAmount.Clear(); }
3. 排序逻辑适配
因为销量列已经指定为整数类型,原有代码中的排序语句会自动按数值大小比较,多位数排序结果完全正确,无需额外改造:
// 该语句可直接保留,适配整数类型的数值排序 this.dataGridView1.Sort(this.dataGridView1.Columns[3], ListSortDirection.Descending);
4. 修复等级统计逻辑
遍历全局数据源的所有行,按销量区间累加计数,按要求的格式输出到对应Label:
private void button2_Click(object sender, EventArgs e) { // 初始化各等级计数 int lvl1Count = 0; int lvl2Count = 0; int lvl3Count = 0; int lvl4Count = 0; // 遍历所有已录入的卖家 foreach (DataRow row in _salesmanTable.Rows) { int sold = (int)row["Antal artiklar"]; // 按区间累加计数 if (sold < 50) lvl1Count++; else if (sold >= 50 && sold < 100) lvl2Count++; else if (sold >= 100 && sold < 200) lvl3Count++; else lvl4Count++; } // 按要求格式输出结果 label8.Text = $"对应等级卖家数量为:{lvl1Count}"; label12.Text = $"对应等级卖家数量为:{lvl2Count}"; label13.Text = $"对应等级卖家数量为:{lvl3Count}"; label14.Text = $"对应等级卖家数量为:{lvl4Count}"; // 执行销量降序排序 dataGridView1.Sort(dataGridView1.Columns[3], ListSortDirection.Descending); }
5. 改造List转换逻辑支撑持久化
移除原有方法里新建空DataTable的冗余逻辑,直接从全局数据源转换强类型List,方便后续做文件存储:
public List<Salesman> GetSalesmanList() { List<Salesman> salesmanList = new List<Salesman>(); foreach (DataRow row in _salesmanTable.Rows) { salesmanList.Add(new Salesman() { Name = row["Namn"].ToString(), SecurityNumber = row["Personnummer"].ToString(), District = row["Distrikt"].ToString(), AmountSold = (int)row["Antal artiklar"] }); } return salesmanList; }
内容的提问来源于stack exchange,提问作者Bornikus
相关产品推荐
相关产品推荐

