MFC扩展库BCGControlBar Pro 怎么用?50万行检测记录的 MFC 表格虚拟化教程

0 阅读4分钟

一套零部件检测软件刚上线时,历史记录可能只有几千条。产线持续运行,尺寸测量、性能测试、质量判定不断写入,列表很快累积到 5 万条、50 万条。数据库能存下这些数据,但桌面端表格却越来越卡:初始化慢、滚动掉帧、内存占用往上蹿。

根子在于普通 Grid 把所有记录都实例化成表格对象。5 万行、10 列就是 50 万个单元格位置,每个单元格还要维护状态、颜色、格式和计算逻辑,开销随行数放大。BCGControlBar Pro 提供的 Virtual Grid,思路不是继续堆对象,而是让 Grid 只记录“有多少行”,等界面滚动到某个位置时,再通过回调向应用取数。这篇文章就来拆解它的用法、回调该写什么,以及选型前必须知道的边界。

检测记录 50 万行,普通 Grid 为什么扛不住?

在检测软件里,一行通常对应一条记录:零件编号、工序、测点、理论值、实测值、公差、时间、判定结果。列数虽然不多,单元格里经常还要加状态色、图标、条件格式。

BCGControlBar Pro 常规的 CBCGPGridCtrl 由行对象和单元格项构成。行数一上去,对象数量就会跟着涨:

  • 5 万行 × 10 列 = 50 万个单元格位置
  • 50 万行 × 10 列 = 500 万个单元格位置

如果每个单元格都带样式或图标,初始化时间、内存占用和刷新体验都会变差。

Virtual Grid 与普通 Grid 到底差在哪?

核心差别在于“数据由谁持有”:普通 Grid 由控件自己持有全部行和单元格对象;Virtual Grid 只保留一个逻辑行数,显示内容通过回调在需要时动态提供。

启用 Virtual Mode
       ↓
设置逻辑行数
       ↓
Grid 请求行列位置
       ↓
应用回调返回显示值

可以把数据库想象成仓库:普通 Grid 是提前把要展示的记录逐条搬上展台;Virtual Grid 则是先登记“仓库里有多少货”,等工程师滚动到某个位置时,再取出对应内容。

实现这两行代码就够了:

grid.EnableVirtualMode(GridCallback);  // 注册取数回调
grid.SetVirtualRows(totalRows);        // 设置逻辑行数

在这里插入图片描述

图1 BCGSoft 官方示例把虚拟行数设为 1 亿,说明 Virtual Mode 的逻辑行数可以配置得很大

对比维度普通 GridVirtual Grid
数据准备应用创建并填充行、单元格先设置逻辑行数
内容获取控件持有已创建的 Grid 对象控件按位置请求,应用回调返回值
更适合数据量可控、直接操作行对象大规模连续记录、按需显示
开发重点行与单元格的创建维护行号映射、缓存与回调效率

回调里该写什么?行号映射与缓存要注意什么

回调的本质是:Grid 告诉应用“我现在要显示第几行第几列”,应用返回对应值。因此回调里最关键的两件事是行号映射数据缓存

行号映射解决“Grid 看到的行号”与“数据记录实际索引”的对应关系。数据已按显示顺序排好,直接按行号取;支持排序或筛选时,回调里要先做一层映射。

数据缓存解决“不要每次取数都查一次数据库”。回调执行频率高,滚动、刷新、重绘都会触发,如果每个单元格都走一次慢查询,界面照样会卡。常见做法是按页预加载一批记录到内存,回调只从缓存里读。

注意: Virtual Grid 只优化了显示层的数据提供方式,不会自动优化数据库查询、网络传输、排序或筛选。回调里的慢查询是性能的第一杀手。

启用 Virtual Mode 前确认:数据总量与典型显示行数、是否支持排序/筛选、缓存策略、回调访问成本。

什么时候该用 Virtual Grid?三种方案怎么选

面对长列表,通常有三条路:

方案适合场景代价
限制单次查询或分页业务天然按工单、日期、批次分段需要重新设计查询和翻页交互
自建虚拟化机制有极强的自定义需求自己处理行号、缓存、刷新、状态同步
BCGControlBar Pro Virtual Grid大规模连续记录,且已在用 BCGControlBar Pro回调和映射逻辑必须写对

连续滚动、定位和对比多的场景,Virtual Grid 值得优先纳入原型测试;业务天然分段时,分页可能更简单。

相关资料