The DataGridView control needs to be used in the system to display data. It adopts the simplest and most commonly used line-by-line filling method and runs well, but the display speed is very slow when there is a large amount of data, considering that the amount of data in the system application scenario is usually more than one million lines, you can only use VirtualMode to fill in.
After checking the information in MSDN, it seems easy to use the virtual mode. You only need to set the VirtualMode attribute of the DataGridView to true, and then complete the CellValueNeeded event processing code. If you need to edit the data, you also need to handle the CellValuePushed event yourself.
Code
/// <Summary>
/// Create a column
/// </Summary>
Void InitialGridViewData ()
{
// Create an ID column
DataGridViewColumn numcol = new DataGridViewTextBoxColumn ();
Numcol. Name = NumberColName;
Numcol. HeaderText = NumberColName;
Numcol. DefaultCellStyle. BackColor = Color. FromArgb (1, 212,208,200 );
Numcol. SortMode = maid. Programmatic;
Numcol. ReadOnly = true;
Numcol. Tag = false;
DataGridView. Columns. Add (numcol );
SoFieldInfos osmFieldInfos = oRst. GetFieldInfos ();
For (int I = 1; I <= osmFieldInfos. Count; I ++)
{
SoFieldInfo osmField = osmFieldInfos [I];
String columnTitle = osmField. Name;
If (! String. IsNullOrEmpty (osmField. Caption ))
ColumnTitle = osmField. Caption;
DataGridViewColumn col = new DataGridViewTextBoxColumn ();
Col. Name = osmField. Name;
Col. HeaderText = columnTitle;
DataGridView. Columns. Add (col );
}
SuSuperMap. ReleaseSmComObject (osmFieldInfos );
OsmFieldInfos = null;
// Fill data in Virtual Mode
DataGridView. VirtualMode = true;
DataGridView. RowCount = oRst. RecordCount + 1;
}
Code
// Cell filling data event
Void dataGridView_CellValueNeeded (object sender, DataGridViewCellValueEventArgs e)
{
// If this is the row for new records, no values are needed.
If (e. RowIndex = this. dataGridView. RowCount)
Return;
// Read data from the record set
String colName = this. dataGridView. Columns [e. ColumnIndex]. Name;
If (colName. Equals (NumberColName ))
{
E. Value = e. RowIndex + 1;
}
Else
{
ORst. MoveTo (e. RowIndex + 1 );
E. Value = oRst. GetFieldValueText (colName );
}
}
After compilation and running, the display speed is very fast, and the user cannot detect the filling time. This is because the virtual mode only fills the small part of the data to be displayed in the current window, refresh data in real time based on the position of the scroll bar. It is not like filling data one by one and then displaying the data at a time when it is bound to the data source. The speed gap naturally cannot be the same as that of the day.
However, a problem is found: the last empty row in the data list is always displayed. This row is a new edit row provided by the control to facilitate the addition of new data. However, my system is only used to edit data and does not add or delete data. How can I remove it?
The first thing that comes to mind is to disable users from appending new rows:
this.dataGridView.AllowUserToAddRows = false;
It has no effect after running, probably because of the virtual mode.
Then, we want to reduce the number of rows in the DataGridView table by one row. Only the existing data rows are displayed, and no new rows are displayed.
Change dataGridView. RowCount = oRst. RecordCount + 1; To dataGridView. RowCount = oRst. RecordCount;
After running again, we found that the newly added edit row at the end still exists, but the data originally displayed was missing one row.
Find the description of this line from MSDN, which has an explanation of the end line, saying that the newly added edit line cannot be controlled in VirtualMode. If the Visible attribute of this row is set to false, an unsupported operation exception is also thrown. With a try-on mentality, I decided to give it a try, So I modified the cell data filling event:
// If this is the row for new records, no values are needed.
if (e.RowIndex >= this.dataGridView.RowCount - 1)
{
this.dataGridView.Rows[e.RowIndex].Visible = false;
return;
}
Unexpectedly, this change is really not displayed, and there is no exception in the operation on MSDN.
When the number of data source records to be displayed is 0, that is, the data itself is empty, an error occurs in the "unsupported operation" mentioned by MSDN, only then can we find that MSDN is not joking with programmers :).
Therefore, you have to add a judgment. If the current data source is empty, the end line is displayed; otherwise, the result is hidden:
Code
// If this is the row for new records, no values are needed.
if (e.RowIndex >= this.dataGridView.RowCount - 1)
{
this.dataGridView.Rows[e.RowIndex].Visible = e.RowIndex == 0 ? true : false;
return;
}
There will be no exception, but when the data source is empty, it will display a single row of blank data, still feel a bit difficult to see.
After a few days, I suddenly remembered, could I add a judgment on the number of rows (RowCount) of the control?
Therefore, a judgment is added at the place where the number of rows is set:
// Fill data in Virtual Mode
DataGridView. VirtualMode = true;
Int recordCount = oRst. RecordCount;
DataGridView. RowCount = recordCount = 0? 0: recordCount + 1;
Now, there will be no more blank lines at the end of the annoying situation, and the system is running normally. However, I still feel a little unwilling at the bottom of my heart. Is there a better solution?
BTW: when filling in the virtual mode, the Automatic sorting mode of the DataGridView SortMode is invalid. You can only implement the sorting function by yourself. In addition, because the virtual mode is to fill in data in real time, the ordering function is actually to sort the data source.