How can I suspend a .NET DataGridView from display开发者_StackOverflow中文版ing anything while I update its Columns?
Here's my current code. It works ok, but it is very slow on the foreach loop; you can see the horiz scroll bar grow slowly as each column is added. I'm building the UI columns myself as I do not want to use dataGridView1.AutoGenerateColumns for various reasons.
// Disconnect and reset DataGridView
dataGridView1.DataSource = null;
dataGridView1.SuspendLayout();
dataGridView1.Columns.Clear();
// Get data from SQL
DataTable dt = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter("select * from employeehist", conn);
adapter.Fill(dt);
// Build DataGridView columns
foreach (DataColumn c in dt.Columns)
{
DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
col.SortMode = DataGridViewColumnSortMode.NotSortable;
col.DataPropertyName = c.ColumnName;
col.HeaderText = c.Caption;
dataGridView1.Columns.Add(col);
}
// Reconnect DataGridView
dataGridView1.DataSource = dt;
dataGridView1.ResumeLayout(true);
You can use VirtualMode with DataGridView in order to very efficiently update the grid. See this article: http://msdn.microsoft.com/en-us/library/ms171622.aspx
From what I remember, it seems to update the entire collection before updating anything on the UI, as opposed to adding to the UI for each new row added/etc.
You may want to consider using the AddRange method instead of Add. The Data Grid behaves a little better when you add them all at once.
DataGridViewColumn[] columns = new DataGridViewColumn[dt.Columns.Count];
for (int i = 0; i < dt.Columns.Count; i++ )
{
DataColumn c = dt.Columns[i];
DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
col.SortMode = DataGridViewColumnSortMode.NotSortable;
col.DataPropertyName = c.ColumnName;
col.HeaderText = c.Caption;
columns[i] = col;
}
dataGridView1.Columns.AddRange(columns);
In my case suspend and resume layout did not work. I resolved disabling the dataGridView (dgv.Enabled = false
) before update and re-enabling it (dgv.Enabled = true
) at the end of the update process.
You could try and prevent it from completely redrawing by using the code in this post. The parent
would be the parent of the dataGridView1
.
Significant performance increase:
var dgv = new DataGridView();
dgv.SuspendLayout();
// Do update, change values
dgv.ResumeLayout();
May not be ultimate high performance.
If you are using timer then use SynchronizingObject. This removes the flickering completly for me.
var dgv = new DataGridView();
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.SynchronizingObject = dgv; // syncronise
timer.Start();
timer.Elapsed += Timer_Elapsed;
void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
refreshDGV(); // in here I refresh the DataGridView
}
This will speed it up 10 times.
dataGridView1.Visible = false;
//Build/populate datagridview
dataGridView1.Visible = true;
It's not the most professional approach but it performs.
精彩评论