如何防止数据网格中的行在应用程序运行时闪烁
在我目前正在开发的应用程序中,我使用 datagridview 来显示数据。要填充它,我必须按一个按钮,后台工作人员将开始运行,它将填充数据表,当它完成运行时,它将使用数据表作为数据网格的数据源。这工作正常,用户界面保持响应等等。 但现在我已经根据它们的值对行实现了着色(我仍在尝试它,所以欢迎任何建议):
private void ApplyColoring()
{
if (dataGridView1.DataSource != null)
{
foreach (DataGridViewRow dataGridRow in dataGridView1.Rows)
{
// hardmap a color to a column
IDictionary<Int32, Color> colorDictionary = new Dictionary<Int32, Color>();
colorDictionary.Add( 7, Color.FromArgb(194, 235, 211));
colorDictionary.Add( 8, Color.Salmon);
colorDictionary.Add( 9, Color.LightBlue);
colorDictionary.Add(10, Color.LightYellow);
colorDictionary.Add(11, Color.LightGreen);
colorDictionary.Add(12, Color.LightCoral);
colorDictionary.Add(13, Color.Blue);
colorDictionary.Add(14, Color.Yellow);
colorDictionary.Add(15, Color.Green);
colorDictionary.Add(16, Color.White);
foreach (DataGridViewRow gridRow in dataGridView1.Rows)
{
foreach (DataGridViewCell cell in gridRow.Cells)
{
if (colorDictionary.Keys.Contains(cell.ColumnIndex))
{
// standard background
cell.Style.BackColor = Color.FromArgb(194, 235, 211);
}
}
}
IList<String> checkedValues = new List<String>();
// first we loop through all the rows
foreach (DataGridViewRow gridRow in dataGridView1.Rows)
{
IDictionary<String, Int32> checkedVal = new Dictionary<String, Int32>();
// then we loop through all the data columns
int maxCol = dnsList.Count + 7;
for (int columnLoop = 7; columnLoop < maxCol; columnLoop++)
{
string current = gridRow.Cells[columnLoop].Value.ToString();
for (int checkLoop = 7; checkLoop < maxCol; checkLoop++)
{
string check = gridRow.Cells[checkLoop].Value.ToString();
if (!current.Equals(check))
{
if (checkedVal.Keys.Contains(current))
{
gridRow.Cells[columnLoop].Style.BackColor = colorDictionary[checkedVal[current]];
}
else
{
gridRow.Cells[columnLoop].Style.BackColor = colorDictionary[columnLoop];
checkedVal.Add(current, columnLoop);
}
}
}
}
}
}
}
}
这给我带来了问题。不是因为着色不起作用,而是因为它起作用。但因为它让它变得非常慢。第一次它运行良好,但是当我再次按下按钮时,它非常慢并且数据网格闪烁。 我希望它作为后处理运行,因此它(或者更确切地说应该)在后台工作程序完成后运行。 但是当我从 RunWorkerCompleted 事件调用 applycoloring 时,速度很慢。我应该怎么做才能防止这种情况发生?如何确保 UI 在执行新查询时不会闪烁(同时不会丢失网格中的当前数据)。
In the application I'm developing at the moment I'm using a datagridview to display data. To fill it, I've to press a button and a backgroundworker will start running, it will fill a datatable and when it's finished running it will use the datatable as the datasource for the datagrid. This works fine, the UI stays responsive et cetera.
But now I've implemented coloring to the rows, depending on their values (Im still playing around with it, so any suggestions are welcome):
private void ApplyColoring()
{
if (dataGridView1.DataSource != null)
{
foreach (DataGridViewRow dataGridRow in dataGridView1.Rows)
{
// hardmap a color to a column
IDictionary<Int32, Color> colorDictionary = new Dictionary<Int32, Color>();
colorDictionary.Add( 7, Color.FromArgb(194, 235, 211));
colorDictionary.Add( 8, Color.Salmon);
colorDictionary.Add( 9, Color.LightBlue);
colorDictionary.Add(10, Color.LightYellow);
colorDictionary.Add(11, Color.LightGreen);
colorDictionary.Add(12, Color.LightCoral);
colorDictionary.Add(13, Color.Blue);
colorDictionary.Add(14, Color.Yellow);
colorDictionary.Add(15, Color.Green);
colorDictionary.Add(16, Color.White);
foreach (DataGridViewRow gridRow in dataGridView1.Rows)
{
foreach (DataGridViewCell cell in gridRow.Cells)
{
if (colorDictionary.Keys.Contains(cell.ColumnIndex))
{
// standard background
cell.Style.BackColor = Color.FromArgb(194, 235, 211);
}
}
}
IList<String> checkedValues = new List<String>();
// first we loop through all the rows
foreach (DataGridViewRow gridRow in dataGridView1.Rows)
{
IDictionary<String, Int32> checkedVal = new Dictionary<String, Int32>();
// then we loop through all the data columns
int maxCol = dnsList.Count + 7;
for (int columnLoop = 7; columnLoop < maxCol; columnLoop++)
{
string current = gridRow.Cells[columnLoop].Value.ToString();
for (int checkLoop = 7; checkLoop < maxCol; checkLoop++)
{
string check = gridRow.Cells[checkLoop].Value.ToString();
if (!current.Equals(check))
{
if (checkedVal.Keys.Contains(current))
{
gridRow.Cells[columnLoop].Style.BackColor = colorDictionary[checkedVal[current]];
}
else
{
gridRow.Cells[columnLoop].Style.BackColor = colorDictionary[columnLoop];
checkedVal.Add(current, columnLoop);
}
}
}
}
}
}
}
}
This is giving me problems. Not because the coloring doesn't work, it does. But because it makes it hella slow. The first time it runs fine, but when i press the button again, it's slow as hell and the datagrid is flickering.
I want this run as postprocess, so it's (or rather should) be run after the backgroundworker is completed.
But when i call applycoloring from the RunWorkerCompleted event its just slow. What should I do to prvent this? How can I make sure the UI doesnt flicker while its executing a new query (while NOT LOSING the current data in the grid).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以打开双缓冲。
VB:
将以下内容放入 Form_Load
对于 C#:转到:修复缓慢滚动的 DataGridView
干杯
you can turn on double buffering.
VB:
put the following e.g. in Form_Load
For C#: go to:Fixing a slow scrolling DataGridView
Cheers
两个建议:
数据。
Two suggestions:
data.
我找到了另一种方法来为慢速数据网格进行反射双缓冲:
创建一个带有一些反射的扩展方法来在数据网格上设置双缓冲:
然后在表单初始值设定项中执行以下操作:
这与 Evolved 的答案非常相似,感谢 Shweta Lodha:
http://www.codeproject.com/Tips/390496/Reducing -DataGridView 中闪烁
I found another way to do the reflection double buffering for slow datagrids:
Create an extension method with some reflection to set double buffering on the datagrid:
Then in the form initializer do:
This is very similar to Evolved's answer and credits go to Shweta Lodha:
http://www.codeproject.com/Tips/390496/Reducing-flicker-blinking-in-DataGridView
打开双缓冲
函数编译所需的命名空间列表为:
然后初始化datagridview
Turn on double buffering
List of namespaces required for the function to compile is:
then initialize datagridview
尝试在更新之前调用 SuspendLayout。不要忘记调用 ResumeLayout。
Try to call SuspendLayout before your updates. Do not forget to call ResumeLayout.
我强烈建议不要循环网格(双缓冲可能有帮助,但它只是“隐藏”真正的问题),因为它会产生大量渲染。
出于这样的目的,我使用事件处理程序:
每当您的单元格值发生更改时,您的网格就会自动更新并更改背景颜色
I would highly recommend not to loop over the grid (double buffering might help but it is just "hiding" the real problem) since it produces a lot of rendering.
For purposes like this I use a eventhandler:
Anytime your cell values change your grid gets automatically updates and changes the back color