Подтвердить что ты не робот

Во время прокрутки FlowLayoutPanel фон искажается + мерцает

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

enter image description here

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

Любые предложения?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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;
        }
    }
}

Ответ 3

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

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

Итак, как вы решаете эту проблему?

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

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

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

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

Ответ 4

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

Ответ 5

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