仅当行适合一页时,DataGridView才会闪烁 [英] DataGridView flickers ONLY when the rows fits roughly one page
问题描述
我有一个尽可能基本的网格视图。它显示一次性的搜索结果,除非再次单击搜索按钮,否则不会更新其数据源,因此我认为数据更新不会导致此问题。
I have a grid view that is as basic as it can gets. It displays a one-off search result, and does not updates its datasource unless the search button is click again, so I don't think data update is causing the issue.
例如,我的搜索返回了30行结果,而我的全屏数据网格可以容纳40行而无需滚动,没有闪烁。然后我开始慢慢降低窗户的高度。一旦网格视图的高度略小于我的30行的高度,它就会开始闪烁。但是,如果我进一步降低窗口的高度,以使网格视图只能显示20行,则会出现一个滚动条,如预期的那样,一切都很好。即使向上或向下滚动也不会闪烁。
For example, my search returns 30 rows of results, and my full-screen data grid could fit 40 rows without scrolling, there are no flickering. Then I started to slowly reduce the height of the window. Once the grid view height is slightly less than my 30 rows' height it starts to flicker. But if I further decrease the height of the window so that the grid view could only shows 20 rows, a scrollbar shows up as expected and everything is fine again. Even scrolling up or down doesn't flicker at all.
尽管我不认为这与性能有关,但我已经尝试过暂停布局和双缓冲等操作不能按预期提供帮助。
Although I don't think it is performance related, I've tried things like suspend layout and double buffering which doesn't help as expected.
我认为这与自动行高计算接近边界条件时有关,但是我不知道如何解决。以下是可能/可能不会影响自动行大小的设置。
I think it is something related to auto row height calculation when it is near its boundary condition, but I have no idea how to solve it. Below are the auto row size settings that might/might not affect it.
dgv.DataSource = datatable;
dgv.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
dgv.Sort(dgv.Columns["Creation Date"], ListSortDirection.Ascending);
dgv.Columns["Creation Date"].SortMode = DataGridViewColumnSortMode.Automatic;
dgv.Columns["Name"].SortMode = DataGridViewColumnSortMode.Automatic;
dgv.Columns["Name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dgv.Columns["Name"].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
dgv.Columns["Receipt No."].SortMode = DataGridViewColumnSortMode.Automatic;
dgv.Columns["Receipt No."].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dgv.Columns["Receipt No."].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
dgv.Columns["Remark"].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
dgv.Columns["Remark"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
这是我的双重缓冲类,以防万一我搞砸了
This is my double buffering class just in case I messed up
public static class BufferedGridView
{
public static void DoubleBuffered(this DataGridView dgv, bool setting)
{
Type dgvType = dgv.GetType();
PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(dgv, setting, null);
}
}
这是我使用它的地方,格式为包含网格视图;
This is where I used it, in the Form that contains the grid view;
public ManagementPage()
{
InitializeComponent();
dgv.DoubleBuffered(true);
.......
}
推荐答案
针对下面的评论,我在下面再次给出了答案。抱歉,我对此站点还很陌生-只是尝试提供帮助。
In response to the comment below, I've set out the answer again below. Sorry, I'm fairly new to this site - just trying to help.
似乎您可以通过覆盖OnCellValueChanged和OnRowHeightChanged事件来打破导致闪烁的无尽循环:
It seems you can break the endless loop that causes the flicker by overriding the OnCellValueChanged and OnRowHeightChanged events:
protected override void OnCellValueChanged(DataGridViewCellEventArgs e)
{
if (e.RowIndex != -1)
{
this.Rows[e.RowIndex].MinimumHeight = 2;
}
base.OnCellValueChanged(e);
}
和
protected override void OnRowHeightChanged(DataGridViewRowEventArgs e)
{
e.Row.MinimumHeight = e.Row.Height;
base.OnRowHeightChanged(e);
}
这基本上将最小行高锁定为更新行高后释放的高度
This basically locks the minimum row height to the height when the row height is updated, and then releases it when the cell value is changed.
因此,当内部DataGridView代码尝试调整行的大小时,它们将被锁定为最小值(这意味着它们不会再次减小大小,这就是导致无限循环的原因。当用户(或代码)更新单元格时,将释放此约束,以便在需要时可以调整行的大小。
Therefore, when the internal DataGridView code tries to resize the rows, they get locked to a minimum (meaning they won't be reduced in size again, which is what causes the endless loop). When a user (or code) updates a cell, this constraint is released so that the rows can resize when they need to.
这篇关于仅当行适合一页时,DataGridView才会闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!