winform_datagridview虚模式
背景:由于项目在UI中一次性加载的数据量有点大,导致后面的数据加载越来越慢。初始化的时候从数据库读取加载的数据也很多,这个过程耗时也很长。
思路:winform默认的表格采用“真绑定”的方式,对载入的数据都会进行全部识别并出个创建row和cell。采用虚模式显示,将数据和表分隔开,数据存在数据源中,表只是动态加载当前需要显示的数据内容。而且对于数据的维护也会更简单,只需要保证_data.Count = datagridview.RowCount;
实现:
首先定义数据:
public readonly BindingList<TaskFile> _tabledata = new BindingList<TaskFile>();
在datagridview的属性中,将VirtualMode改为true,并手动设置双缓冲为true(因为该属性为只读
FormLoad:{ EnableDoubleBuffer(this.dgStudentInfo,true); } public static void EnableDoubleBuffer(DataGridView dgv, bool enable = true) { var pi = typeof(DataGridView) .GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); pi?.SetValue(dgv, enable); }
在构造函数或则界面加载中,给_data绑定一个事件,每次data改变的时候,同步到datagridview中
_tabledata.ListChanged += (s, e) => { // 统一用安全调用器回到 UI 线程 SafeInvoke(this, () => { this.datagridview.RowCount = _tabledata.Count; this.datagridview.Invalidate(); // 立即重绘 }); };
在需要改变数据的地方,直接对_tabledata进行增删改
lock (_dataLock) { _tabledata.Add(curentTaskFile); }
最后就是在datagridview的事件中,写入自己的数据和cell绑定刷新的事件:
private void datagridview_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { try { if (_tabledata == null || _tabledata.Count <= 0) return; if (e.RowIndex < 0 || e.RowIndex >= _tabledata.Count) return; var row = _tabledata[e.RowIndex]; if(this.datagridview.Rows[e.RowIndex].Tag == null) this.datagridview.Rows[e.RowIndex].Tag = row; string data = row.data; if (e.ColumnIndex == 0) { e.Value = EnumAnalyse.Normal; } if (e.ColumnIndex == 1) e.Value = e.RowIndex + 1; if (e.ColumnIndex == 2) { if (row.state != 0) e.Value = EnumHelper.GetDisplayAttributeName(typeof(ASheetExceptionType), row.aSheetExceptionType); else e.Value = row.stateRemark; } if (e.ColumnIndex == 3) { if (row.isUpload == 1 && row.isCloudSync == 1) e.Value = "已上传"; else e.Value = "待上传"; } PaperInfoDto answerInfos = FileInfo(row); if(e.ColumnIndex == 4) { e.Value = row.Name; } if(e.ColumnIndex==5) { e.Value = answerInfos.Number; } if (data != "null" && data.Length > 0) { if (aInfos != null) { for (int j = 0; j < aInfos.datas.Count; j++) { if (e.ColumnIndex >= 6) { if(!string.IsNullOrEmpty(aInfos.datas[e.ColumnIndex - 6].Content)) e.Value = aInfos.datas[e.ColumnIndex - 6].Content; else e.Value = "-"; } } } } else { for (int j = 0; j < NumberAry.Length; j++) { if (e.ColumnIndex >= 6) e.Value = "-"; } } } catch (Exception ex) { Utils._log.Error($"CellValueNeeded 异常:RowIndex={e.RowIndex}, Count={_tabledata.Count}, {ex}"); } }

浙公网安备 33010602011771号