我有一个绑定到BindingSource的WinForms DataGridView,而BindingSource又绑定到100,000个对象的BindingList .
BindingList<MyObject> myObjectList = new BindingList<MyObject>();
BindingSource bindingSourceForMyObjects = new BindingSource();
bindingSourceForMyObjects.DataSource = myObjectList;
dataGridViewMyObjects.DataSource = bindingSourceForMyObjects;
我有一个事件处理程序连接到我的DataGridView的CellValueChanged事件,其中包含以下代码:
dataGridViewMyObjects.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Red;
dataGridViewMyObjects.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.White;
因此,当我的用户更改一行时,此事件处理程序将触发并将红色行更改为白色以指示数据已更改 . 这很好但我也有一些情况需要以编程方式更改基础列表,我也希望这些更改能够反映在DataGridView中 . 为了实现这一点,我的对象类实现了INotifyPropertyChanged,并且我有一个连接到BindingSource的ListChanged事件的事件处理程序 . 该事件处理程序中的代码如下所示:
if (e.ListChangedType == ListChangedType.ItemChanged)
{
dataGridViewMyObjects.Rows[e.NewIndex].DefaultCellStyle.BackColor = Color.Red;
dataGridViewMyObjects.Rows[e.NewIndex].DefaultCellStyle.ForeColor = Color.White;
}
这也是有效的,如果我以编程方式修改50个对象,DataGridView行也会更新 . 但是,正如我之前所说的,我有100,000个对象正在处理,如果我需要修改超过800个对象,可能需要一段时间,因为我的对象中所有对OnPropertyChanged()的调用 . 在绝对最坏的情况下,如果我需要修改所有100,000个对象,可能需要将近1分钟才能完成 .
在我的对象类中,我有一个布尔变量,当我以编程方式进行“批量”更新(> 800个对象)时,我用它来避免触发OnPropertyChanged()调用 . 这使得更快地更新对象属性,但是由于绕过了双向绑定,因此DataGridView中的相应行不再更新其前色/后色值 . 我知道哪些行对应于被修改的对象,我尝试循环遍历它们并更新ForeColor / BackColor值,但同样,此操作完成需要将近一分钟 .
我已经尝试将该循环包装在......
dataGridViewMyObjects.SuspendLayout();
// loop here
dataGridViewMyObjects.ResumeLayout();
但这似乎没有对性能产生影响 . 有没有更快的方法为很多行设置ForeColor / BackColor,或者我看到的速度只是我正在使用的数据大小的问题?
1 回答
要尝试的一件事是告诉窗口在循环更改时停止绘制控件 . 从How do I suspend painting for a control and its children?
然后你的代码看起来像这样: