作者:皇皇
信息化时代,项目里面数据量达到几十上百万是经常遇到的事情,浏览这些数据的时候我们往往采取分页的方式。但是在一些特殊情况下需要把数据一起加载出来,比如说GIS行业里面,已经获取到了所有矢量对象,希望把这些对象的属性信息展示出来。如果用DataGridView或者ListView采用最简单、常用的逐行填充法,运行没问题,但是在大数据量的时候显示速度非常慢,体验效果很差,那我们怎么才能做到短时间内把所有数据加载出来呢?
查看资料,发现用DataGridView的虚模式就可以解决逐行填充速度慢的问题,因为虚模式只填充当前窗口中需要显示的那一小部分数据,实时根据滚动条位置刷新数据,并不是像逐条填充和数据源绑定时一次性将数据填充完成再显示。用31万条数据做了个测试,用虚模式和逐条填充两种方式,同一个设备逐条填充用时30多分钟,虚模式几乎无法察觉它的填充时间。
通过行列号和数据索引的关系实现对数据的编辑。
代码演示
下面我们通过对超图矢量数据的操作,来演示对大数据的快速浏览和编辑。
1、瞬间浏览
首先把DataGridView的VirtualMode属性设置为true,创建列。
//创建列
FieldInfos mFieldInfos = oRst.GetFieldInfos();
for (int i = 0; i < mFieldInfos.Count; i++)
{
FieldInfo mField = mFieldInfos[i];
string columnTitle = mField.Name;
if (!string.IsNullOrEmpty(mField.Caption))
columnTitle = mField.Caption;
DataGridViewColumn col = new DataGridViewTextBoxColumn();
col.Name = mField.Name;
col.HeaderText = columnTitle;
if (mField.IsSystemField)
{
col.ReadOnly = true;
col.DefaultCellStyle.BackColor = Color.FromArgb(240, 240, 240);
}
dataGridViewNew.Columns.Add(col);
}
mFieldInfos = null;
//采用虚模式来填充数据
dataGridViewNew.VirtualMode = true;
dataGridViewNew.Rows.Add(oRst.RecordCount);
然后完成DataGridView的CellValueNeeded事件填充数据
// 单元格填充数据事件
private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
if (e.RowIndex == this.dataGridViewNew.RowCount)
return;
// 从记录集中读取数据
string colName = this.dataGridViewNew.Columns[e.ColumnIndex].Name;
oRst.MoveTo(e.RowIndex);
e.Value = oRst.GetFieldValue(colName);
}
图一
2、数据编辑
数据编辑的时候,不是去编辑DataGridView里面的数据,而是通过用户点击的行列号去匹配数据集里面的索引,找到对应的数据,对数据进行编辑,编辑完成后重新加载数据。
以修改数据集为例,当用户双击单元格修改数据的时候获取单元格的行列号,确定单元格位置大小,然后在单元格位置放置一个控件,比如编辑日期,首先获取单元格位置及大小
//指定单元格位置、大小
private Rectangle SizeAndBounds(int RowIndex, int ColumnIndex)
{
Size _Size = this.dataGridViewNew.Rows[upRowIndex].Cells[upColumnIndex].Size;
int cellX = dataGridViewNew.GetCellDisplayRectangle(upColumnIndex, upRowIndex, false).X;
int cellY = dataGridViewNew.GetCellDisplayRectangle(upColumnIndex, upRowIndex, false).Y;
int x = dgvX + cellX;
int y = dgvY + cellY;
Rectangle _Rectangle = new Rectangle(cellX, cellY, _Size.Width, _Size.Height);
return _Rectangle;
}
设置DateTimePicker的Bounds,然后添加到dataGridViewNew的Controls组里面
_DateTimePicker.Bounds = _Rectangle;
dataGridViewNew.Controls.Add(_DateTimePicker);
图二
DateTimePicker时间修改后失去焦点时,就把DateTimePicker的值修改到数据集里面
通过行号定位到记录集
oRst.SeekID(e.RowIndex+1);
通过列号定位到记录集的列名
FieldInfos fieldInfos = oRst.GetFieldInfos();
string names = fieldInfos[e.ColumnIndex].Name;
根据列名修改数据
String time=_DateTimePicker.Text;
DateTime dt = DateTime.Parse(time);
addData = oRst.SetFieldValue(names, dt);
把日期控件删除掉,再重新加载数据就OK了