22

我有一个应用程序,上面有很多控件。而且它有大量的闪烁,尤其是在启动时。

我对它应用了这个修复

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED
            return cp;
        }
    } 

这效果很好 - 闪烁减少了令人难以置信的数量。但是,副作用是窗口右上角的最小化、最大化和关闭按钮在我将鼠标移到或单击它们时没有动画(尽管它们仍然有效)。这给应用程序一种挂起的感觉。

如何在保留最大化、最小化和关闭按钮的可用性的同时保留 WS_EX_COMPOSITED?

这发生在 Windows XP 上。正如@fallenidol 指出的那样,这在 Windows 7 上不是问题。

4

5 回答 5

14

我想到了。诀窍是在显示表单后删除 WS_EX_COMPOSITED 标志。我的博客上的完整解释和代码:

如何消除 Windows 窗体应用程序上的闪烁

于 2010-07-21T23:39:48.153 回答
8

我知道这个问题有点老了,但迟到总比没有好。我使用了您链接的原始示例,想出了一个在调整大小时将其打开,然后将其关闭以完美绘制其他所有内容的示例。希望它可以帮助其他人寻找解决此问题的方法。正如 OP 所知,DoubleBuffering 单独的属性不能解决闪烁问题。

这是一种解决方法,可以在用户调整表单大小时停止闪烁,但不会弄乱 DataGridView、NumericUpDown 等控件的绘制。假设您的表单名称是“Form1”:

int intOriginalExStyle = -1;
bool bEnableAntiFlicker = true;

public Form1()
{
    ToggleAntiFlicker(false);
    InitializeComponent();
    this.ResizeBegin += new EventHandler(Form1_ResizeBegin);
    this.ResizeEnd += new EventHandler(Form1_ResizeEnd);
}

protected override CreateParams CreateParams
{
    get
    {
        if (intOriginalExStyle == -1)
        {
            intOriginalExStyle = base.CreateParams.ExStyle;
        }
        CreateParams cp = base.CreateParams;

        if (bEnableAntiFlicker)
        {
            cp.ExStyle |= 0x02000000; //WS_EX_COMPOSITED
        }
        else
        {
            cp.ExStyle = intOriginalExStyle;
        }

        return cp;
    }
} 

private void Form1_ResizeBegin(object sender, EventArgs e)
{
    ToggleAntiFlicker(true);
}

private void Form1_ResizeEnd(object sender, EventArgs e)
{
    ToggleAntiFlicker(false);
}

private void ToggleAntiFlicker(bool Enable)
{
    bEnableAntiFlicker = Enable;
    //hacky, but works
    this.MaximizeBox = true;
}
于 2011-06-28T19:50:35.843 回答
4

试试下面的代码。这应该放在主窗体和您拥有的任何其他自定义用户控件中。

        // Enable double duffering to stop flickering.
        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);
于 2010-07-20T14:00:03.613 回答
0

您应该尝试称为 DoubleBuffered 的标准 Windows 窗体控件属性。 http://msdn.microsoft.com/en-us/library/system.windows.forms.control.doublebuffered.aspx

于 2010-07-20T07:14:18.557 回答
0

我刚看到这篇文章,意识到它有点老了。但是,我的表单遇到了同样的问题,并且发现(对于 XP,无论如何)一个不优雅的解决方案似乎没有启用视觉样式。

于 2012-12-09T18:23:43.530 回答