在我的应用程序中,我有一个DataGridView控件,显示所选对象的数据.当我选择一个不同的对象(在上面的组合框中)时,我需要更新网格.不幸的是,不同的对象具有完全不同的数据,甚至是不同的列,因此我需要清除所有现有数据和列,创建新列并添加所有行.当这样做时,整个控件可怕地闪烁,需要很长时间.是否有一种通用的方法来使控件处于更新状态,因此它不会重新绘制自身,然后在完成所有更新后重新绘制它?
TreeViews当然可以:
myTreeView.BeginUpdate(); try { //do the updates } finally { myTreeView.EndUpdate(); }
是否有通用的方法与其他控件,特别是DataGridView一起执行此操作?
更新:对不起,我不确定我是否足够清楚.我看到"闪烁",因为在单次编辑后,控件在屏幕上重新绘制,因此您可以看到滚动条缩小等.
双缓冲在这里没有用,因为只有双缓冲油漆操作,OP看到的闪烁是多次油漆操作的结果:
清除控制内容 - >重新绘制
清除列 - >重绘
填充新列 - >重绘
添加行 - >重绘
所以四次重新绘制以更新控件,因此闪烁.不幸的是,并非所有标准控件都有BeginUpdate/EndUpdate,它会在调用EndUpdate之前删除所有重绘调用.这是你可以做的:
对每个数据集和显示/隐藏控件具有不同的控件,
从其父级删除控件,更新,然后再次添加控件,
写下你自己的控件.
选项1和2仍然会闪烁一点.
在我正在研究的.Net GUI程序上,我创建了一组消除所有闪烁的自定义控件.
.NET控件支持SuspendLayout和ResumeLayout方法.选择适当的父控件(即托管要填充的控件的控件)并执行以下操作:
this.SuspendLayout(); // Do something interesting. this.ResumeLayout();
人们似乎忘记了一个简单的解决方法:
Object.Visible = false; //do update work Object.Visible = true;
我知道它看起来很奇怪,但是有效.当对象不可见时,它不会重绘自身.您但是,仍然需要做的begin
和end
更新.
不是一次添加一个数据网格的行,而是使用该DataGridView.Rows.AddRange
方法一次添加所有行.这应该只更新一次显示.DataGridView.Columns.AddRange
列也有同样的功能.