datagridview virtual mode, update RowCount causes CellValueNeeded to fire for all rows
我正在尝试实现datagridview的虚拟模式,但是当我将RowCount设置为某个数字(以显示滚动条)时,网格希望一次拥有所有行,而不仅仅是显示的行。
1 2 3 4 5 | DataGridView grid = new ...; grid.VirtualMode = true; grid.CellValueNeeded += OnCellValueNeeded; grid.RowCount = dataprovider.GetFullCount(); |
如何告诉网格仅请求显示的行?
这只是一个猜测,但是您是否已将AutoSizeRowsMo??de或AutoSizeColumnsMode值设置为AllCells或将任何列设置为该值?尝试将调整大小模式设置为"无"或仅设置为" DisplayedCells",然后查看是否仍然存在问题。
不确定这是否与我遇到的问题相同,但是当定期大幅度更改VirtualMode DataGridView上的RowCount时,我的确获得了非常差的性能。
我注意到滚动条在"缓慢地"变化;即看起来好像是在个别删除我的虚拟行(!)。
无论如何,在每次调用
在设置完整计数之前,应将RowCount设置为零。
1 2 3 4 5 | DataGridView grid = new ...; grid.VirtualMode = true; grid.CellValueNeeded += OnCellValueNeeded; grid.RowCount = 0; grid.RowCount = dataprovider.GetFullCount(); |
不幸的是,这似乎是标准行为。我可以通过
解决
1 2 3 4 5 6 7 8 9 10 | void OnCellValueNeeded(...) { if(!_active) return; } grid.VirtualMode = true; grid.CellValueNeeded += OnCellValueNeeded; _active = false; grid.RowCount = dataprovider.GetFullCount(); _active = true; |
或在后台线程中使用复杂的懒惰获取实现IBindingList,ITypedList
更新:问题现在似乎已解决。我无法使用以下命令重现它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | static class Program { private static Form form; private static int i; [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var grid = new DataGridView { Dock = DockStyle.Fill, VirtualMode = true, AllowUserToAddRows = false, Columns = { new DataGridViewTextBoxColumn { HeaderText ="foo" }, new DataGridViewTextBoxColumn { HeaderText ="bar" }, }, }; grid.CellValueNeeded += OnCellValueNeeded; form = new Form { Controls = { grid } }; //grid.RowCount = 0; grid.RowCount = 10000; Application.Run(form); } private static void OnCellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { i++; form.Text = i.ToString(); e.Value ="fooValue"; } } |
我遇到了同样的问题,并且像您一样尝试了设置活动标志的解决方案,并且还尝试了在设置新标志之前将RowCount设置为0(或grid.Rows.Clear())的解决方案。 RowCount。
这两种方法都提高了性能,但都没有对其进行足够的改进以使其达到我想要的即时性,因为我正在根据搜索框的输入实时动态地过滤网格。
我发现了另外两个解决方案:
1)使用分页,这样一来您就不必将RowCount设置得很高。如果您已经在使用分页(在这种情况下您就不会在这里了),那么我认为这是一个很好的解决方案,但是如果您不打算实现它,那么这将是一个过于繁琐的解决方案。
2)将调用置于其自己的线程中以设置RowCount。这是我要尝试的。坦率地说,如果您在线程仍在结束时尝试编辑单元格,则不确定此代码的安全性,但是我想我会很快发现的。
编辑:
好的,所以我尝试将其线程化,希望能达到目的,因为我在其他地方读到它确实对另一个人有所帮助。如果您只是偶尔更改一次值,这似乎是一个很好的解决方案,但是如果您连续多次(我是这样),它仍然会挂起。我认为这是因为您必须使用Invoke(),并且第二次仍在等待第一个完成。不能说我完全理解这笔交易是什么,但是我决定暂时只使用空白行,因为当我将它们留在那里时,它的SOOO更快,更简单。