C# 在WinForms(例如DataGridView)中更新控件时闪烁
在我的应用程序中,我有一个DataGridView控件,用于显示选定对象的数据。当我选择一个不同的对象(在上面的组合框中)时,我需要更新网格。不幸的是,不同的对象有完全不同的数据,甚至不同的列,所以我需要清除所有现有的数据和列,创建新的列并添加所有的行。当这项工作完成时,整个控件会可怕地闪烁,而且需要很长时间。有没有一种通用方法可以让控件处于更新状态,这样它就不会重新绘制自己,然后在我完成所有更新后重新绘制它 使用TreeView当然是可能的:C# 在WinForms(例如DataGridView)中更新控件时闪烁,c#,.net,winforms,C#,.net,Winforms,在我的应用程序中,我有一个DataGridView控件,用于显示选定对象的数据。当我选择一个不同的对象(在上面的组合框中)时,我需要更新网格。不幸的是,不同的对象有完全不同的数据,甚至不同的列,所以我需要清除所有现有的数据和列,创建新的列并添加所有的行。当这项工作完成时,整个控件会可怕地闪烁,而且需要很长时间。有没有一种通用方法可以让控件处于更新状态,这样它就不会重新绘制自己,然后在我完成所有更新后重新绘制它 使用TreeView当然是可能的: myTreeView.BeginUpdate();
myTreeView.BeginUpdate();
try
{
//do the updates
}
finally
{
myTreeView.EndUpdate();
}
对于其他控件,尤其是DataGridView,是否有一种通用的方法可以做到这一点
更新:对不起,我不确定我是否足够清楚。我看到“闪烁”,因为在单次编辑后,控件会在屏幕上重新绘制,因此您可以看到滚动条收缩等等。听起来您需要双缓冲:
尽管这主要用于单个控件,但您可以在Windows窗体控件或窗体中实现它。不幸的是,我认为thins可能只是.net framework的副产品。我正在经历类似的闪烁,尽管有自定义控件。我读过的许多参考资料都表明了这一点,同时双缓冲方法也未能为我消除任何闪烁。双缓冲在这里没有帮助,因为只有双缓冲绘制操作,OP看到的闪烁是多个绘制操作的结果:
- 清除控件内容->重新绘制
- 清除列->重新绘制
- 填充新列->重新绘制
- 添加行->重新绘制
在我正在开发的.NETGUI程序中,我创建了一组自定义控件,消除了所有闪烁 该.NET控件支持和方法。选择适当的父控件(即承载要填充的控件的控件)并执行以下操作:
this.SuspendLayout();
// Do something interesting.
this.ResumeLayout();
使用
DataGridView.rows.AddRange
方法一次添加所有行,而不是一次添加一行数据网格。这应该只更新显示一次。还有一个DataGridView.Columns.AddRange
可以对列执行相同的操作。这对我很有用
基本上,它涉及从所需控件派生并设置以下样式
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
人们似乎忘记了一个简单的解决方法:
Object.Visible = false;
//do update work
Object.Visible = true;
我知道这看起来很奇怪,但这很管用。当对象不可见时,它不会重新绘制自身。但是,您仍然需要执行
开始
和结束
更新。您也可以尝试这项工作
public static void DoubleBuffered(Control formControl, bool setting)
{
Type conType = formControl.GetType();
PropertyInfo pi = conType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(formControl, setting, null);
}
我尝试了双缓冲,但没有多大帮助。我认为问题在于,它在我添加的每一行之后都会尝试重新绘制,因此它最终会多次更新第一行。是的,我很确定这就是问题所在。因为我必须添加>50行,所以可以看到网格是如何增长的。当您创建控件时,您扩展了现有的数据网格视图,或者从头开始编写了一个新的数据网格视图?我从头开始编写它们,源自UserControl,它们都是非常特定于应用程序的。干杯,这似乎是DataGridViews可以获得的最好结果。这应该有更多的要点,会为我节省很多时间。其他建议对我的用例不起作用,但这是完美的。谢谢将其添加到DataGridView双缓冲区中(true);