Проблемы перерисовки изображения на элементе управления с двойной буферизацией без мерцания - PullRequest
1 голос
/ 04 февраля 2009

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

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Emgu.UI
{
    public class DoubleBufferedPictureBox : Control
    {
        const BufferedGraphics NO_MANAGED_BACK_BUFFER = null;

        BufferedGraphicsContext GraphicManager;
        BufferedGraphics ManagedBackBuffer;

        public Bitmap Bitmap { get; set; }
        public Rectangle DrawRectangle { get; set; }

        public DoubleBufferedPictureBox()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);

            GraphicManager = BufferedGraphicsManager.Current;
            GraphicManager.MaximumBuffer =
                   new Size(Width + 1, Height + 1);
            ManagedBackBuffer =
                GraphicManager.Allocate(CreateGraphics(),
                                               ClientRectangle);

            Resize += DoubleBufferedPictureBox_Resize;
        }

        void DoubleBufferedPictureBox_Resize(object sender, EventArgs e)
        {
            if (ManagedBackBuffer != NO_MANAGED_BACK_BUFFER)
                ManagedBackBuffer.Dispose();

            GraphicManager.MaximumBuffer =
                  new Size(Width + 1, Height + 1);

            ManagedBackBuffer =
                GraphicManager.Allocate(CreateGraphics(),
                                                ClientRectangle);
            Refresh();
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            ManagedBackBuffer.Graphics.DrawImage(Bitmap, DrawRectangle);
            ManagedBackBuffer.Render(pe.Graphics);
        }

    }
}

Есть идеи?

Ответы [ 5 ]

2 голосов
/ 05 февраля 2009

Вы используете .Net 2.0? Если это так, то я обнаружил, что следующие стили Windows делают свое дело, даже с использованием старых упорных элементов управления Win32, и это тоже быстро!

// Note the >>> Optimized <<< DoubleBuffer
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);

Убедитесь, что вы всегда рисуете из сообщения WM_PAINT, иначе оно будет мигать. Вам больше ничего не нужно, все автоматически.

2 голосов
/ 04 февраля 2009

Боже мой ...

Как я уже сказал в своих комментариях, pictureBox содержится в другом элементе управления, который я не написал (но у которого есть источник). Оказывается, мерцание вызвано этими двумя строками:

if (pictureBox.Width != _displayedImage.Width) pictureBox.Width = _displayedImage.Width;
if (pictureBox.Height != _displayedImage.Height) pictureBox.Height = _displayedImage.Height;

Я думаю, это потому, что PictureBox на самом деле закреплен в родительском контроле ...

В любом случае, спасибо за все ваши ответы.

0 голосов
/ 04 февраля 2009

Является ли рисование в родительском элементе управления (форма?) Также с двойной буферизацией?

Ваш пользовательский элемент управления может быть нарисован без мерцания, но в дальнейшем, когда родительский элемент управления окрашен и не имеет двойной буферизации, он мигает.

Вы можете дважды буферизовать неправильную вещь.

0 голосов
/ 04 февраля 2009

Я думаю, что проблема в вашем методе OnPaint, из MSDN , когда вы вызываете свой метод ManagedBackBuffer.Render, вы должны передать CreateGraphics (), а не свойство Graphics:

0 голосов
/ 04 февраля 2009

Вы пробовали установить для свойства DoubleBuffered элементов управления значение true?

...