关于c#:在WinForms中的控件更新期间闪烁(例如DataGridView)

关于c#:在WinForms中的控件更新期间闪烁(例如DataGridView)

Flickering during updates to Controls in WinForms (e.g. DataGridView)

在我的应用程序中,我有一个DataGridView控件,该控件显示所选对象的数据。 当选择其他对象时(在上面的组合框中),我需要更新网格。 不幸的是,不同的对象具有完全不同的数据,甚至具有不同的列,因此我需要清除所有现有数据和列,创建新列并添加所有行。 完成此操作后,整个控件将可怕地闪烁,并且需要很长时间。 有没有一种通用的方法可以使控件处于更新状态,以便它不会重新绘制自身,而是在完成所有更新后重新绘制它?

TreeViews当然是可能的:

1
2
3
4
5
6
7
8
9
myTreeView.BeginUpdate();
try
{
    //do the updates
}
finally
{
    myTreeView.EndUpdate();
}

是否有通用方法可以与其他控件(特别是DataGridView)一起使用?

更新:对不起,我不确定我是否足够清楚。 我看到"闪烁",因为在单次编辑后,控件将重新绘制在屏幕上,因此您可以看到滚动条缩小等。


人们似乎忘记了一个简单的解决方案:

1
2
3
4
5
Object.Visible = false;

//do update work

Object.Visible = true;

我知道这看起来很奇怪,但是可以。当对象不可见时,它不会重绘自身。但是,您仍然需要进行beginend更新。


.NET控件支持SuspendLayout和ResumeLayout方法。选择适当的父控件(即托管要填充的控件的控件),然后执行以下操作:

1
2
3
4
5
this.SuspendLayout();

// Do something interesting.

this.ResumeLayout();


双缓冲在这里无济于事,因为只有双缓冲绘画操作,OP看到的闪烁是多次绘画操作的结果:

  • 清除控件内容->重新绘制
  • 清除列->重涂
  • 填充新列->重新绘制
  • 添加行->重画

因此需要四次重绘以更新控件,从而实现闪烁。不幸的是,并非所有标准控件都具有BeginUpdate / EndUpdate,它将删除所有重画调用,直到调用EndUpdate。您可以执行以下操作:

  • 每个数据集都有不同的控件,并显示/隐藏控件,
  • 从其父项中删除该控件,进行更新,然后再次添加该控件,
  • 编写自己的控件。
  • 选项1和2仍会闪烁。

    在我正在使用的.Net GUI程序上,我创建了一组自定义控件,这些控件消除了所有闪烁。


    而不是一次添加一个数据网格的行,而是使用DataGridView.Rows.AddRange方法一次添加所有的行。那应该只更新一次显示。还有一个DataGridView.Columns.AddRange对列执行相同的操作。


    这对我有用。

    http://www.syncfusion.com/faq/windowsforms/search/558.aspx

    基本上,它涉及从所需的控件派生并设置以下样式。

    1
    2
    3
    SetStyle(ControlStyles.UserPaint, true);
    SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    SetStyle(ControlStyles.DoubleBuffer, true);

    不幸的是,我认为Thins可能只是.net框架的副产品。尽管使用自定义控件,但我也遇到了类似的闪烁。我阅读的许多参考资料都表明了这一点,同时双重缓冲方法无法消除任何闪烁。


    听起来像您想要双重缓冲:

    http://www.codeproject.com/KB/graphics/DoubleBuffering.aspx

    尽管此方法主要用于单个控件,但是您可以在Windows Forms控件或Form中实现它。


    您也可以尝试此操作。

    1
    2
    3
    4
    5
    6
    public static void DoubleBuffered(Control formControl, bool setting)
    {
        Type conType = formControl.GetType();
        PropertyInfo pi = conType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
        pi.SetValue(formControl, setting, null);
    }

    推荐阅读

      linux启动显示命令行?

      linux启动显示命令行?,系统,密码,终端,状态,首页,情况,基础,电脑,信息,工具,l

      linux显示之前的命令?

      linux显示之前的命令?,系统,信息,命令,地址,服务,环境,数据,标准,数字,不了,l

      linux打开显示器命令?

      linux打开显示器命令?,信息,工具,系统,环境,发行,实时,数据,设备,命令,文件,L

      linux命令实时显示?

      linux命令实时显示?,系统,实时,时间,信息,情况,命令,对比,电脑,名称,一致,lin

      linux外部命令显示?

      linux外部命令显示?,系统,工具,命令,一致,盘中,软件,技术,外部,内部,文件夹,L

      linux命令显示ip?

      linux命令显示ip?,地址,系统,网络,信息,技术,电脑,手机,设备,服务,管理,配置L

      linux编译时显示命令?

      linux编译时显示命令?,系统,基础,工具,代码,百度,下来,网上,命令,内核,文件,L

      linux显示运行命令?

      linux显示运行命令?,系统,服务,状态,信息,工具,数据,电脑,标准,管理,时间,如

      显示linux网卡命令行?

      显示linux网卡命令行?,系统,信息,工具,网络,服务,电脑,网卡,技术指标,地址,

      linux命令显示内容?

      linux命令显示内容?,标准,系统,数据,命令,百度,实时,时间,信息,文件,内容,lin

      linux常用显示命令?

      linux常用显示命令?,工作,地址,系统,信息,管理,命令,目录,标准,功能,常用命

      linux用命令显示账号?

      linux用命令显示账号?,密码,系统,信息,地址,电脑,名字,用户,命令,用户名,用

      linux命令行同步显示?

      linux命令行同步显示?,地址,工具,系统,数据,工作,时间,命令,综合,网址,信息,L

      linux命令显示窗口?

      linux命令显示窗口?,系统,工具,首页,终端,密码,命令,窗口,界面,桌面,选项,lin

      linux分页显示命令?

      linux分页显示命令?,工具,通信,命令,数据,信息,管道,标准,位置,一致,系统,lin

      linux中ps命令显示?

      linux中ps命令显示?,系统,信息,状态,进程,命令,多地,软件,工作,基础,报告,lin

      linux命令逐页显示?

      linux命令逐页显示?,系统,工作,地址,命令,网上,信息,百度,基础,标准,内容,在l

      linux显示内核命令?

      linux显示内核命令?,地址,发行,信息,工具,电脑,系统,名称,内核,版本,状态,如

      显示等号linux命令?

      显示等号linux命令?,工作,地址,信息,系统,命令,目录,标准,管理,基础,常用命

      linux中显示路径命令?

      linux中显示路径命令?,系统,地址,工作,信息,时间,命令,数据,网络,路径,名字,l