9

双缓冲不适用于组合框。有没有其他方法可以避免在 Windows 窗体中闪烁?

我有一个窗口窗体,其中包含多个面板。根据我的菜单选择,我一次只显示一个面板。

我有一个图标面板、一个标题面板和组合框。根据该组合框的选定项目,gridview1 和 2 正在填充。当我使用键盘向下箭头快速选择组合框项目时,图标面板和标题面板总是在重新绘制。我需要保持两者不变。这两个面板在我更改组合框选定索引时产生一些闪烁效果(即,它们正在闪烁或闪烁)。有什么办法可以避免这种闪烁。?我尝试在表单构造函数和表单加载事件中启用双缓冲。请帮忙..............

InitializeComponent();
                this.SetStyle(ControlStyles.DoubleBuffer, true);
                this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
                this.SetStyle(ControlStyles.UserPaint, true);
                this.SetStyle(ControlStyles.SupportsTransparentBackColor, false);
                this.SetStyle(ControlStyles.Opaque, false);
                this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
                this.SetStyle(ControlStyles.ResizeRedraw, true);

我在表单构造函数和表单加载事件中尝试了这段代码

4

3 回答 3

33

另一个解决方案:

//TODO: Don't forget to include using System.Runtime.InteropServices.

internal static class NativeWinAPI
{
    internal static readonly int GWL_EXSTYLE = -20;
    internal static readonly int WS_EX_COMPOSITED = 0x02000000;

    [DllImport("user32")]
    internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32")]
    internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
}

您的表单构造函数应如下所示:

public MyForm()
{
    InitializeComponent();

    int style = NativeWinAPI.GetWindowLong(this.Handle, NativeWinAPI.GWL_EXSTYLE);
    style |= NativeWinAPI.WS_EX_COMPOSITED;
    NativeWinAPI.SetWindowLong(this.Handle, NativeWinAPI.GWL_EXSTYLE, style);
}

在上面的代码中,您可能会更改this.Handle为类似MyFlickeringPanel.Handle

您可以在此处阅读更多相关信息:Extended Window Styles和此处:CreateWindowEx

设置 WS_EX_COMPOSITED 后,窗口的所有后代都使用双缓冲从下到上绘制顺序。自下而上的绘制顺序允许后代窗口具有半透明(alpha)和透明度(颜色键)效果,但前提是后代窗口也设置了 WS_EX_TRANSPARENT 位。双缓冲允许在不闪烁的情况下绘制窗口及其后代。

于 2012-10-10T10:13:42.073 回答
4
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams handleParam = base.CreateParams;
            handleParam.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED       
            return handleParam;
        }
    }
于 2014-12-03T07:06:11.627 回答
2

解决方案#1:在添加项目之前
使用。ComboxBox.BeginUpdate()这将防止每次将项目添加到列表时Control重新绘制。ComboBox添加项目后,您可以使用ComboBox.EndUpdate()重新绘制。

解决方案#2

private void EnableDoubleBuffering()
{
    this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
}
于 2012-10-10T07:20:19.263 回答