我正在尝试实现datagridview的虚拟模式,但是当我将RowCount设置为某个数字(以显示滚动条)时,网格想要同时拥有所有行,而不仅仅是显示的。
DataGridView grid = new ...;
grid.VirtualMode = true;
grid.CellValueNeeded += OnCellValueNeeded;
grid.RowCount = dataprovider.GetFullCount();
如何告诉网格只请求显示的行?
答案 0 :(得分:4)
这只是一个猜测,但您是将AutoSizeRowsMode或AutoSizeColumnsMode值设置为AllCells还是设置为该列的任何列?尝试将调整大小模式设置为无或仅显示DisplayedCells并查看是否仍有问题。
答案 1 :(得分:2)
不确定这是否与我遇到的问题相同,但是当我在VirtualMode DataGridView上经常大幅更改RowCount时,我确实得到了非常差的性能。
我注意到滚动条正在“慢慢地”变化;即它看起来像是单独删除我的虚拟行(!)。
无论如何,在每次调用grid.Rows.Clear()
之前执行grid.RowCount = n
会大幅改善效果。
答案 2 :(得分:0)
void OnCellValueNeeded(...)
{
if(!_active) return;
}
grid.VirtualMode = true;
grid.CellValueNeeded += OnCellValueNeeded;
_active = false;
grid.RowCount = dataprovider.GetFullCount();
_active = true;
或实现IBindingList,ITypedList在后台线程中使用复杂的延迟抓取
更新:现在问题似乎已解决。我无法再使用以下内容重现它:
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";
}
}
答案 3 :(得分:0)
我遇到了同样的问题,我尝试了像你一样设置活动标志的解决方案,我也尝试了在设置新的之前将RowCount设置为0(或grid.Rows.Clear())的解决方案行数。
这两件事都提高了性能,但是它们都没有足够快,因为我根据搜索框的输入实时动态过滤网格。
我找到了另外两个解决方案:
1)使用分页,这样您就不必将RowCount设置得如此之高。我认为这是一个很好的解决方案,如果你已经使用分页(在这种情况下你不会在这里),但如果你没有计划实现它,那就太麻烦了。
2)调用将RowCount设置为自己的线程。这是我即将尝试的那个。老实说,如果你在线程仍在完成时尝试编辑单元格,那么这个单元是多么安全,但我想我很快就会发现。
编辑:
好的,所以我试着穿上它,希望能做到这一点,因为我在其他地方读到这真的帮助了另一个人。它似乎是一个很好的解决方案 IF 你只是偶尔改变一下这个值,但是如果你连续多次这样做(我就是这样)它仍然会挂起。我想这是因为你必须使用Invoke(),第二次它还在等待第一次完成。不能说我完全理解这笔交易是什么,但是我决定暂时使用空白行,因为当我把它们留在那里时它的SOOO更快更简单。
答案 4 :(得分:0)
在设置完整计数之前,应将RowCount设置为零。
DataGridView grid = new ...;
grid.VirtualMode = true;
grid.CellValueNeeded += OnCellValueNeeded;
grid.RowCount = 0;
grid.RowCount = dataprovider.GetFullCount();