2008-09-15 112 views
7

在我的应用程序中,我有一个DataGridView控件显示所选对象的数据。当我选择一个不同的对象(在上面的组合框中)时,我需要更新网格。不幸的是,不同的对象有完全不同的数据,甚至是不同的列,所以我需要清除所有现有的数据和列,创建新列并添加所有行。当这样做完成后,整个控制系统会发生可怕的闪烁,并且需要很长时间。是否有一种通用的方式来获取控件的更新状态,以便它不重绘本身,然后在完成所有更新后重新绘制它?在更新WinForms中的控件时闪烁(例如DataGridView)

这当然是可能的的TreeView:

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

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

更新:对不起,我不确定我是否清楚。我看到的“闪烁”,因为单一的编辑后的控制获取屏幕上重新绘制,所以你可以看到滚动条萎缩等

+0

在您的DataGridView DoubleBuffered(true)中添加此项; – 2017-08-02 05:39:30

回答

7

而不是一次添加数据网格之一行,请使用DataGridView.Rows.AddRange方法可以一次添加所有行:承载要填充),并完成类似下面的控件控制。这应该只更新显示一次。还有一个DataGridView.Columns.AddRange为列做同样的事情。

+0

干杯,这似乎是最好的,你可以用DataGridView – Grzenio 2008-09-16 08:35:38

1

听起来像是你想双缓冲:

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

尽管这主要用于单个控件,但您可以在Windows窗体控件或窗体中实现此功能。

+2

我试过双缓冲,但没有多大帮助。我认为问题在于,它会在我添加的每一行之后尝试重新绘制,因此它会多次更新第一行。 – Grzenio 2008-09-15 15:56:16

1

不幸的是,我认为这可能只是.net框架的副产品。尽管使用自定义控件,但我正在经历类似的闪烁现象。我读过的许多参考资料都表明了这一点,除此之外,双缓冲方法未能为我消除任何闪烁。

6

双缓冲不会帮助这里,因为,只有双缓冲器油漆操作,OP是看到闪烁的是多个涂料操作的结果:

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

所以这是四个重新刷新更新控制,因此闪烁。不幸的是,并不是所有的标准控件都有BeginUpdate/EndUpdate,它将删除所有的重绘调用,直到EndUpdate被调用。这里是你可以做什么:

  1. 有不同的控制设置的每个数据和显示/隐藏控件,
  2. 来自其母公司,更新删除控件,然后再添加控制,
  3. 写下您的自己控制。

选项1和2仍会闪烁一下。

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

+0

是的,我很确定这就是问题所在。而且因为我必须添加> 50行,你可以看到网格是如何增长的。 当你创建你的控件时,你扩展了现有的数据网格视图,还是从头开始写一个新的? – Grzenio 2008-09-15 16:38:30

+0

我从头开始编写它们,派生自UserControl,它们都是非常特定于应用程序的。 – Skizz 2008-09-16 08:08:05

8

.NET控件支持SuspendLayoutResumeLayout方法。选择适当的家长控制(即

this.SuspendLayout(); 

// Do something interesting. 

this.ResumeLayout(); 
+2

是的,我试过了,但它只是不工作:( – Grzenio 2008-09-16 08:34:50

7

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

Object.Visible = false; 

//do update work 

Object.Visible = true; 

我知道这似乎不可思议,但工程。当对象不可见时,它不会重绘自己。但是,您仍然需要执行beginend更新。

0

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

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