要解决的目标:如何让 Datagridview 快速平滑显示大量数据

通常,Winform 下的表格控件是很“低效”的,如 DataGrid 和 DataGridView。造成低效的原因在于在默认的设定下,它们都诚实的和数据源做了“真绑定”,这种绑定无论你使用了那种方式对数据源进行载入和管理,表格控件都会和全部的数据一一进行认识,并根据它们的数量和类型,逐个创建行和单元格。——也就是说,数据源有1万个单元格,表格控件默认就会对这1万个数据进行认识和创建并显示出来,怎么能不慢。

注:数据源是指和表格控件绑定的或通过其它方式对表格控件赋值的所有数据来源,并非数据库中的所有数据。

解决方式两点,虚模式显示和双缓冲加持。

虚模式,VirtualMode = true。是 DataGridView 中一个属性,当开启时显示转为虚模式显示,和不开启的区别就是

不开启时,显示不显示,用不用的着的单元格都会被创建和使用,开启后,只有当单元格显示或被使用时,才按需引发事件

个人理解就是,虚模式当某位置单元格需要被显示或处理业务时,表格控件会通过引发各类事件通知代码,要求提供下一步动作,从而大幅度节省“不需要的开销”。比如一个窗体上能显示100个单元格时,就对这100个做请求,编码人员可以根据位置提供这100个单元格的内容,窗体上永远最多显示100个。位置是固定的,内容是变化的。

实现方法是:

  • 首先开启 VirtualMode = true
  • 为 DataGridView 添加列,用于显示数据
  • 为 DataGridView 添加行,这将会引发RowNeeded事件和CellValueNeeded事件,从而可以在事件中处理对被需要的单元格赋予何值。
const int initialSize = 3000;
//get data
dataPool = await DataTransfer.GetData(AppConfig.DbConnectionString, "grades", 1, 3000); dgvShow.Rows.Clear();
dgvShow.Columns.Clear();
dgvShow.VirtualMode = true;
dgvShow.ReadOnly = true; foreach(DataColumn col in dataPool.Columns)
{
dgvShow.Columns.Add(col.ColumnName, col.ColumnName);
}
//此句用于控制 DataGridView 显示行数,同时起到添加行引发事件的作用
dgvShow.RowCount = initialSize; private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
if (dataPool != null)
{
e.Value = dataPool.Rows[e.RowIndex][e.ColumnIndex];
}
}

上面的代码,先获取到拥有3000行数据的 DataTable,然后设定 DataGridView 开启虚模式并“创建”行来引发相关事件。在 CellValueNeeded 中将数据表中对应数据显示到表格控件中。

上面的行为只是解决了部分问题,避免了表格控件的性能的严重浪费,但数据较多时会发现拉动时依旧会“卡”,这就要解决平滑显示的问题。

使用双缓冲来解决

using System.Reflection;
... public void DoubleBuffered(DataGridView dgv, bool setting)
{
Type dgvType = dgv.GetType();
PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(dgv, setting, null);
}

上面的代码利用反射,对表格控件的 DoubleBuffered 属性进行设定,为什么不能直接设定?因为其 DoubleBuffered 是 protected 的,不使用反射无法访问。

#.NET# DataGrid显示大量数据——DataGridView虚模式的更多相关文章

  1. winform DataGridView的虚模式填充,CellValueNeeded事件的触发条件

    虚模式填充常用来处理大量数据,某个字段的显示问题. DataGridView是.net 2.0新增的表格数据编辑和显示控件,简单的数据显示和编辑,只需直接和数据源绑定就可以了. 对于 一些特殊情况,我 ...

  2. C#将dataGridView中显示的数据导出到Excel(大数据量超有用版)

    开发中非常多情况下须要将dataGridView控件中显示的数据结果以Excel或者Word的形式导出来,本例就来实现这个功能. 因为从数据库中查找出某些数据列可能不是必需显示出来,在dataGrid ...

  3. 清除DataGridView显示的数据

    一.DataGridView未绑定数据时清空数据 this.dgv_PropDemo.DataSource = null 二.DataGridView绑定数据时清空数据 DataGridView绑定了 ...

  4. silverlight DataGrid 显示篇

    silverlight DataGrid 显示篇 分类: Silverlight2012-05-12 21:55 693人阅读 评论(0) 收藏 举报 datagridsilverlightbindi ...

  5. EasyUI datagrid 在ie8和360兼容模式兼容性问题

    问题:easyui中的datagrid在ie8和360兼容模式下显示不出来. 答案:不是easyui的问题.是引入的jquery版本问题.jquery-1.5.1抛异常,这个版本是mvc3自带的jqu ...

  6. 解决easyui datagrid加载数据时,checkbox列没有根据checkbox的值来确定是否选中

    背景:   昨天帮朋友做一个easyui datagrid的小实例时,才发现easyui datagrid的checkbox列,没有根据值为true或false来选中checkbox,当时感觉太让人失 ...

  7. easyui datagrid显示进度条控制操作

    在当我们需要控制时间前台实际项目页面datagrid显示进度条的数据加载时运行,和datagrid默认情况下只在有url加载运行时的数据显示方式的进度条.下面的代码手动控制: 打开一个进度条: $(' ...

  8. 【转】让浏览器格式化显示JSON数据之chrome jsonView插件安装

    jsonView 用来让Chrome浏览器能格式化的显示JSON数据. 以上是网上找的方式,且试验成功! 步骤: 1.打开 https://github.com : 2.搜索 jsonView 链接: ...

  9. Cocos2d 利用继承Draw方法制作可显示三维数据(宠物三维等)的三角形显示面板

    很久没有写博客了,这段时间比较忙,又是搬家又是做自己的项目,还有太多琐碎的事情缠身,好不容易抽出时间把最近自己做的一些简单例子记录一下. 在我的项目中,我需要一个显示面板来显示游戏中的一个三维数据,例 ...

随机推荐

  1. centos环境下登录mysql报 ERROR 1045 (28000)怎么解决

    centos环境下登录mysql报 ERROR 1045 (28000)怎么解决 新入手一台虚拟机,Centos7系列的操作系统,安装mysql后,执行连接出现了Mysql ERROR 1045 (2 ...

  2. Adobe Photoshop CC 2015安装激活教程

    Adobe Photoshop CC 2015安装激活教程(附序列号) Adobe Photoshop CC 2015是Adobe针对旗下的创意云Creative Cloud 套装推出了2015年年度 ...

  3. CodeForces 513A Game (水题,博弈)

    题意:两个人有n1,n2个球,然后分别最多拿出 k1,k2个球,然后扔掉,谁先拿完谁输. 析:很简单么,每人都足够聪明,就每次扔一个好了,那么,谁的球多,谁就能赢呗,如果相等,那么第一个扔的输. 代码 ...

  4. ios中改变UIImagePickerController页面的button的文字为中文

    可以在工程中直接 project-->info-->Localization native development region   赋值为 zh_CN

  5. Ubuntu 14.04 install emacs 24.5

    1.前期准备工作 2.安装基础构件工具 3.下载emacs编译需要的依赖库 4.下载emacs24.5编译安装 5.下载并安装我的emacs配置文件 6.配置tmux和zsh 1. 前期准备工作 在阿 ...

  6. jsp request 获取路径

    这篇教程不错:http://zjutsoft.iteye.com/blog/1084260 自己试验如下: System.out.println("-----------------serv ...

  7. linux系统上查看硬件信息

    一:查看CPU more /proc/cpuinfo | grep "model name" grep "model name" /proc/cpuinfo 如 ...

  8. sql2008 获取表结构说明

    SELECT     表名       = case when a.colorder=1 then d.name else '' end,    表说明     = case when a.color ...

  9. Hadoop集群 -Eclipse开发环境设置

    1.Hadoop开发环境简介 1.1 Hadoop集群简介 Java版本:jdk-6u31-linux-i586.bin Linux系统:CentOS6.0 Hadoop版本:hadoop-1.0.0 ...

  10. PARTITION BY函数

    1.PARTITION BY 开窗函数, 使用场景,在合同表里,获取所有房源在最新的合同编号.或者获取每个班级每次考试的第一名. 区别聚合函数:对于每个每个分组返回多行,而聚合函数对于每个分组只返回一 ...