Мерцание в приложении Windows Forms

У меня есть приложение, которое имеет массу элементов управления на нем. И он имеет огромное количество мерцания, особенно при запуске.

я применил этот исправить к нему.

    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.

5 ответов


Я понял. Трюк состоит в том, чтобы удалить флаг WS_EX_COMPOSITED после отображения формы. Полное объяснение и код в свой блог:

Как избавиться от мерцания в приложениях Windows Forms


Я знаю, этот вопрос немного старая, но лучше поздно, чем никогда. Я использовал ваш оригинальный пример, который вы связали, чтобы придумать тот, который переключает его при изменении размера, а затем переключает его обратно, чтобы нарисовать все остальное идеально. Надеюсь, это поможет другим найти решение этой проблемы. Как известно OP, свойства DoubleBuffering не решают мерцающие проблемы.

вот обходной путь, чтобы остановить мерцание, когда пользователь изменяет размер формы, но не испортить рисунок управления как элемент, элемент управления 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;
}

попробуйте следующий код. Это должно идти в основной форме и любые другие пользовательские элементы управления у вас есть.

        // 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);

вы должны попробовать стандартное свойство управления windows forms с именем DoubleBuffered. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.doublebuffered.aspx


Я только что наткнулся на этот пост и понимаю, что он немного старый. Однако у меня такая же проблема с моей формой и обнаружена (для XP, во всяком случае) неэлегантное решение, похоже, не позволяет визуальные стили.