Двойная буферизация с панелью - PullRequest
4 голосов
/ 27 сентября 2011

Двойная буферизация всей формы может быть выполнена путем установки значения для элементов управления «AllPaintingInWmPaint», «UserPaint» и «DoubleBuffer» равными «true» (this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true)).

Но это не может произойти с System.Windows.Forms.Panel, потому что класс не позволяет мне это делать. Я нашел одно решение: http://bytes.com/topic/c-sharp/answers/267635-double-buffering-panel-control. Я также пробовал это: Winforms двойной буферизации . Это тормозит, даже когда он используется на маленьком чертеже, у меня есть некоторые пользовательские ресурсы, которые я использую в форме, и другие вещи, из-за которых я не буду превращать всю форму в один чертеж. И второй, кажется, вызывает проблемы. Есть ли другие способы сделать это?

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

Ответы [ 3 ]

9 голосов
/ 27 сентября 2011

Используйте PictureBox, если вам не нужна поддержка прокрутки, он по умолчанию имеет двойной буфер. Получить прокручиваемую панель с двойной буферизацией достаточно просто:

using System;
using System.Windows.Forms;

class MyPanel : Panel {
    public MyPanel() {
        this.DoubleBuffered = true;
        this.ResizeRedraw = true;
    }
}

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

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

1 голос
/ 21 сентября 2016

Я должен был опубликовать свое решение давным-давно ...

Ну, вот мое решение:

Bitmap buffer = new Bitmap(screenWidth, screenHeight);//set the size of the image
System.Drawing.Graphics gfx = Graphics.FromImage(buffer);//set the graphics to draw on the image
drawStuffWithGraphicsObject(gfx);//draw
pictureBox1.Image = buffer;//set the PictureBox's image to be the buffer

Позволяет мне почувствовать себя полным идиотом в поиске этого решения спустя годы после постановки этого вопроса.

Я пробовал это с панелью, но она оказалась медленнее при применении нового изображения. Где-то я читал, что лучше использовать Panel вместо PictureBox. Я не знаю, нужно ли мне что-то добавлять в код, чтобы ускорить процесс для Panel.

1 голос
/ 27 сентября 2011

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

...