双缓冲列表框 [英] Double buffered ListBox

查看:235
本文介绍了双缓冲列表框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个的CheckedListBox(的WinForms)控制(继承自列表框,谷歌上搜索显示,这个问题是与列表框)的锚定在其形式四面。当窗体大小时,列表框有一个丑陋的闪烁。我想继承的CheckedListBox和设置 DoubleBuffered 的构造函数(这种技术的工作原理与其他控件,包括ListView和的DataGridView ),但它没有任何效果。

I have a CheckedListBox (WinForms) control (which inherits from ListBox; googling shows that the problem is with ListBox) that is anchored to all four sides of its form. When the form is resized, the ListBox has an ugly flicker. I tried inheriting CheckedListBox and setting DoubleBuffered to true in the ctor (this technique works with other controls, including ListView and DataGridView), but it had no effect.

我尝试添加的 WS_EX_COMPOSITED 风格的CreateParams ,帮,反而使得形态调整糊状更慢。

I tried adding the WS_EX_COMPOSITED style to CreateParams, and this helped, but makes the form resize mush more slowly.

是否有任何其他的方式来prevent这种闪烁?

Is there any other way to prevent this flickering?

推荐答案

我有虽然有一个所有者绘制的列表框类似的问题。我的解决办法是使用BufferedGraphics对象。你的情况可能与此解决方案各不相同,如果你的列表不是所有者绘制,但也许它会给你一些启发。

I was having similar issues albeit with an owner drawn listbox. My solution was to use BufferedGraphics objects. Your mileage may vary with this solution if your list isn't owner drawn, but maybe it will give you some inspiration.

我发现TextRenderer有困难渲染到正确的位置,除非我suppled TextFormatFlags。preserveGraphicsTranslateTransform。在可以替代的是使用P ​​/ Invoke来调用的BitBlt图形上下文之间直接复制像素。我选择了这是两害相权取其轻。

I found that TextRenderer had difficulties rendering to the correct location unless I suppled TextFormatFlags.PreserveGraphicsTranslateTransform. The alternative to this was to use P/Invoke to call BitBlt to directly copy pixels between the graphics contexts. I chose this as the lesser of two evils.

/// <summary>
/// This class is a double-buffered ListBox for owner drawing.
/// The double-buffering is accomplished by creating a custom,
/// off-screen buffer during painting.
/// </summary>
public sealed class DoubleBufferedListBox : ListBox
{
    #region Method Overrides
    /// <summary>
    /// Override OnTemplateListDrawItem to supply an off-screen buffer to event
    /// handlers.
    /// </summary>
    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;

        Rectangle newBounds = new Rectangle(0, 0, e.Bounds.Width, e.Bounds.Height);
        using (BufferedGraphics bufferedGraphics = currentContext.Allocate(e.Graphics, newBounds))
        {
            DrawItemEventArgs newArgs = new DrawItemEventArgs(
                bufferedGraphics.Graphics, e.Font, newBounds, e.Index, e.State, e.ForeColor, e.BackColor);

            // Supply the real OnTemplateListDrawItem with the off-screen graphics context
            base.OnDrawItem(newArgs);

            // Wrapper around BitBlt
            GDI.CopyGraphics(e.Graphics, e.Bounds, bufferedGraphics.Graphics, new Point(0, 0));
        }
    }
    #endregion
}

这篇关于双缓冲列表框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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