在更新WinForms中的控件期间闪烁(例如DataGridView)

在我的应用程序中,我有一个DataGridView控件,显示所选对象的数据。 当我选择一个不同的对象(在上面的combobox中)时,我需要更新网格。 不幸的是,不同的对象具有完全不同的数据,甚至是不同的列,因此我需要清除所有现有数据和列,创建新列并添加所有行。 完成后,整个控件可怕地闪烁,需要很长时间。 是否有一种通用的方法来使控件处于更新状态,因此它不会重新绘制自身,然后在完成所有更新后重新绘制它?

TreeViews当然可以:

myTreeView.BeginUpdate(); try { //do the updates } finally { myTreeView.EndUpdate(); } 

有没有通用的方法与其他控件,特别是DataGridView这样做?

更新:对不起,我不确定我是否足够清楚。 我看到“闪烁”,因为在单次编辑后,控件在屏幕上重新绘制,因此您可以看到滚动条缩小等。

不是一次添加一个数据网格的行,而是使用DataGridView.Rows.AddRange方法一次添加所有行。 这应该只更新一次显示。 还有一个DataGridView.Columns.AddRange为列做同样的事情。

.NET控件支持SuspendLayout和ResumeLayout方法。 选择适当的父控件(即托管要填充的控件的控件)并执行以下操作:

 this.SuspendLayout(); // Do something interesting. this.ResumeLayout(); 

双缓冲在这里没有帮助,因为只有双缓冲油漆操作,OP看到的闪烁是多次油漆操作的结果:

  • 清除控制内容 – >重新绘制
  • 清除列 – >重绘
  • 填充新列 – >重绘
  • 添加行 – >重绘

所以四次重新绘制以更新控件,因此闪烁。 遗憾的是,并非所有标准控件都具有BeginUpdate / EndUpdate,它会在调用EndUpdate之前删除所有重绘调用。 这是你可以做的:

  1. 对每个数据集和显示/隐藏控件具有不同的控件,
  2. 从其父级删除控件,更新,然后再次添加控件,
  3. 写下你自己的控件。

选项1和2仍然会闪烁一点。

在我正在研究的.Net GUI程序中,我创建了一组消除所有闪烁的自定义控件。

人们似乎忘记了一个简单的解决方法:

 Object.Visible = false; //do update work Object.Visible = true; 

我知道它看起来很奇怪,但是有效。 当对象不可见时,它不会重绘自身。 但是,您仍然需要进行beginend更新。

这对我有用。

http://www.syncfusion.com/faq/windowsforms/search/558.aspx

基本上它涉及从所需的控件派生并设置以下样式。

 SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.DoubleBuffer, true); 

听起来你想要双缓冲:

http://www.codeproject.com/KB/graphics/DoubleBuffering.aspx

虽然这主要用于单个控件,但您可以在Windows窗体控件或窗体中实现它。

不幸的是,我认为这些可能只是.net框架的副产品。 我正在经历类似的闪烁,虽然有自定义控件。 我读过的许多参考资料都表明了这一点,以及双缓冲方法无法消除任何闪烁的事实。

你可以尝试这个,它的工作。

 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); }