为什么我的WinForm控件在绘制事件之前会闪烁?

时间:2014-01-20 10:17:12

标签: c# winforms

我有一个表单,我在其中加载了一个用户控件,其中包含3个其他用户控件。

每当我移动到另一个标签并返回到该用户控件时,它内部的3个控件就会闪烁,甚至会引发任何事件。

我尝试了所有事情,包括:

this.DoubleBuffered = true;
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);

protected override CreateParams CreateParams
{
    get
    {
        CreateParams baseParams = base.CreateParams;
        baseParams.ExStyle |= 0x0200000;
        return baseParams;
    }
}

protected override CreateParams CreateParams
{
    get
    {
        CreateParams baseParams = base.CreateParams;
        baseParams.ExStyle &= 0x0200000;
        return baseParams;
    }
}

但没有任何帮助。任何代码运行都会发生闪烁。

可能是什么问题?

2 个答案:

答案 0 :(得分:4)

这可能会发生,因为每次都会画背景。

如果 all 你的绘画是在OnPaint()完成的(包括清除你的嵌套用户可能正在做的背景 - 那么应该没问题),那么你可以完全禁用背景画如下:

protected override void OnPaintBackground(PaintEventArgs pevent)
{
    // Do nothing to disable background painting.
}

您可能会发现在执行一个或多个嵌套用户控件时也需要这样做。

此外,如果您要自定义现有的Windows控件以防止它闪烁,您有时必须执行以下操作(但这不是您应该为其中一个用户控件执行的操作):

private const int WM_ERASEBKGND = 20;

[PermissionSet(SecurityAction.Demand, Unrestricted=true)]

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_ERASEBKGND)
    {
        m.Result = IntPtr.Zero;
    }
    else
    {
        base.WndProc(ref m);
    }
}

在自定义ListView时我必须这样做,以防止它闪烁。

答案 1 :(得分:1)

如果您在标签中绘制了大量元素,则可以尝试按照here所述禁用并恢复“重绘”。