仅当行适合一页时,DataGridView才会闪烁 [英] DataGridView flickers ONLY when the rows fits roughly one page

查看:82
本文介绍了仅当行适合一页时,DataGridView才会闪烁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个尽可能基本的网格视图。它显示一次性的搜索结果,除非再次单击搜索按钮,否则不会更新其数据源,因此我认为数据更新不会导致此问题。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆