Несмотря на двойную буферизацию, бегущая строка по-прежнему мерцает

Есть идеи как избавиться от мерцания? Я исследовал SO, Интернет и пробовал много разных вещей, например, поместить TickerControl в панель с двойной буферизацией а-ля Двойная буферизация, когда не рисовал в OnPaint (): почему это не работает? и т. Д. много других вещей. Он по-прежнему мерцает, но не при каждой перерисовке, но пару раз в секунду.

Кроме того, даже после удаления «g.Clear (BackColor)» в OnPaint, что-то все еще должно очищать фон, поскольку текст продолжает прокручиваться читаемо.

Вот соответствующие части моего класса TickerControl:

class TickerControl : Control
{
    private static readonly StringFormat stringFormat = new StringFormat(StringFormatFlags.NoWrap);

    private const int padding = 40;
    private const int scrollSleep = 10;
    private const int scrollAdvancePixels = 1;

    private float textWidth;
    private float currentX;

    private static readonly Timer scrollTimer = new Timer();

    public TickerControl()
    {
        this.SetStyle(ControlStyles.UserPaint |
                      ControlStyles.AllPaintingInWmPaint |
                      ControlStyles.OptimizedDoubleBuffer
                      , true);
        scrollTimer.Tick += AdvanceText;
        scrollTimer.Interval = scrollSleep;
        scrollTimer.Enabled = true;
    }

    private void AdvanceText(object sender, EventArgs e)
    {
        if (IsDisposed)
            return;

        currentX -= scrollAdvancePixels;
        if (currentX <= -textWidth)
            currentX = 0;
        Invalidate();
    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;

        g.Clear(BackColor);

        using (SolidBrush brush = new SolidBrush(ForeColor))
        {
            g.DrawString(Text, Font, brush, currentX, 0, stringFormat);
            g.DrawString(Text, Font, brush, currentX + textWidth, 0, stringFormat);
        }
    }

Есть идеи?

Обновление:

Поскольку Саллушан предложил ручную двойную буферизацию, позвольте мне добавить, что я пробовал это раньше, используя приведенный ниже код. Но на экране он выглядит точно так же, как показано выше, поэтому проблема, похоже, не в моем методе OnPaint. Я предполагаю, что это должно быть где-то в настройках моего Control.

    private Bitmap backBuffer;

    protected override void OnPaint(PaintEventArgs e)
    {
        if (backBuffer == null)
            backBuffer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);

        Graphics g = Graphics.FromImage(backBuffer);

        g.Clear(BackColor);

        using (SolidBrush brush = new SolidBrush(ForeColor))
        {
            g.DrawString(Text, Font, brush, currentX, 0, stringFormat);
            g.DrawString(Text, Font, brush, currentX + textWidth, 0, stringFormat);
        }

        g.Dispose();

        e.Graphics.DrawImageUnscaled(backBuffer, 0, 0);
    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        // Don't call base!
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        if (backBuffer != null)
        {
            backBuffer.Dispose();
            backBuffer = null;
        }
        base.OnSizeChanged(e);
    }

5
задан Community 23 May 2017 в 11:45
поделиться