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

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

Я применил этот fix к нему.

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

Это сработало отлично - мерцание было уменьшено довольно невероятной суммой. Однако побочный эффект заключается в том, что кнопки "Свернуть", "Максимизировать" и "Закрыть" в правом верхнем углу окна не оживляют, когда я нажимаю на них или нажимаю на них (они все еще работают). Это придает приложению ощущения.

Как сохранить WS_EX_COMPOSITED, сохраняя при этом удобство кнопок Maximize, Minimize и Close?

Это происходит в Windows XP. Как отметил @fallenidol, это не проблема Windows 7.

Ответ 2

Я знаю, что этот вопрос немного стар, но лучше поздно, чем никогда. Я использовал ваш оригинальный пример, который вы связали, чтобы придумать тот, который переключает его при изменении размера, а затем переключает его назад, чтобы полностью рисовать все остальное. Надеюсь, это поможет другим найти решение этой проблемы. Как известно 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;
}

Ответ 3

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

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

Ответ 5

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