Во время прокрутки FlowLayoutPanel фон искажается + мерцает - PullRequest
14 голосов
/ 27 июля 2010

У меня есть приложение Windows Form, у которого есть фон. Внутри него у меня есть Flowlayoutpanel с прозрачным фоном. Когда я прокручиваю, происходит следующее:

enter image description here

Я также вижу мерцание. Я перепробовал весь бизнес с двойной буферизацией, и он не работает.

Есть предложения?

Ответы [ 5 ]

18 голосов
/ 24 мая 2012

это то, что у меня сработало.

public class CustomFlowLayoutPanel : FlowLayoutPanel
{
    public CustomFlowLayoutPanel()
        : base()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    }

    protected override void OnScroll(ScrollEventArgs se)
    {
        this.Invalidate();

        base.OnScroll(se);
    }
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x02000000; // WS_CLIPCHILDREN
            return cp;
        }
    }
}
10 голосов
/ 27 июля 2010

Да, это не работает. Вот класс, который несколько улучшает его:

using System;
using System.Windows.Forms;

class MyFlowLayoutPanel : FlowLayoutPanel {
    public MyFlowLayoutPanel() {
        this.DoubleBuffered = true;
    }
    protected override void OnScroll(ScrollEventArgs se) {
        this.Invalidate();
        base.OnScroll(se);
    }
}

Скомпилируйте и перетащите его из верхней части панели инструментов на форму. Однако он не может решить фундаментальную проблему, параметр «Показать содержимое окна при перетаскивании». Это системный параметр, он будет включен для более поздних версий Windows. Когда он включен, Windows сама прокручивает содержимое панели, а затем просит приложение нарисовать ту часть, которая была обнаружена при прокрутке. Метод OnScroll отменяет это, гарантируя, что все окно будет перекрашено, чтобы сохранить фоновое изображение на месте. Конечный результат не очень хорош, вы увидите, что изображение делает «pogo», прыгая вверх и вниз во время прокрутки.

Единственное исправление для этого - отключение системной опции. Это не практичное решение, пользователям нравится опция, и она влияет на каждую программу, а не только на вашу. Если вы не можете жить с Pogo, вам придется отказаться от прозрачности.

3 голосов
/ 27 апреля 2014

Я добавил Application.DoEvents () в событие Scroll объекта FlowPanel, которое остановило размывание дочерних элементов управления FlowPanel, которые я получал.

3 голосов
/ 05 декабря 2011

Мне очень приятно сообщить, что Ганс и Интернет в целом (просто изучите WPF .... pfffft) здесь не правы.

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

Так как же решить эту проблему?

  1. Установите прокручиваемый элемент управления на DoubleBuffered.

  2. Поймать сообщения WM_HSCROLL / WM_VSCROLL. Invalidate. Установите для флага do_not_paint значение true. Вызовите base.WndProc (). Установите флаг "do_not_paint" в false. Обновление.

  3. Поймать WM_PAINT и связанные сообщения. Вызывайте base.WndProc () только в том случае, если флаг do_not_paint имеет значение false.

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

1 голос
/ 08 августа 2013

Немного поздно ... но это случается, если вы возитесь с Color.Transparent.Проверьте, имеет ли ваш FlowLayoutPanel прозрачный фон.Если это так, попробуйте изменить это.

...