Двойная буферизация с панелью

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

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


person AlexSavAlexandrov    schedule 27.09.2011    source источник
comment
Я думаю, это зависит от того, что вы пытаетесь сделать. Вы пытаетесь обновить данные или анимацию? Вы пытаетесь сделать игру? Я помню, как было очень сложно удалить мерцание с помощью system.drawing, даже с двойной буферизацией (иногда частота кадров настолько низкая, что это выглядит как мерцание даже при двойной буферизации)   -  person wllmsaccnt    schedule 27.09.2011
comment
Это игра, в которую играют в окне WinForms. Рисунок нанесен на панно. Рисунок изменяется, когда пользователь нажимает на панель. Но когда есть процессы прокрутки и изменения размера, тоже есть мерцание.   -  person AlexSavAlexandrov    schedule 27.09.2011
comment
Вы можете найти решение здесь, у меня это сработало. [Решение] [1] [1]: stackoverflow.com/questions/16882921/   -  person Ahmed Yossef    schedule 16.04.2014


Ответы (3)


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

using System;
using System.Windows.Forms;

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

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

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

person Hans Passant    schedule 27.09.2011
comment
Я могу попытаться избавиться от некоторых элементов управления, но их будет немного ... Я попробую создать новый класс Panel и разблокировать некоторые функции System.Windows.Forms.Panel. Но спасибо за ссылку. Это удобный учебник. - person AlexSavAlexandrov; 27.09.2011
comment
Ганс, как заменить старую панель на новую? Я написал этот класс, теперь как мне подключить его к моему существующему panel1, чтобы он получил вышеупомянутые атрибуты? - person Romy; 22.06.2016
comment
Удалите панель 1 из формы и поместите ее на место. Вы можете переименовать его в панель1, чтобы существующий код продолжал работать. - person Hans Passant; 22.06.2016
comment
Я пробовал это и получаю ошибки двусмысленности между панелью 1 - person Romy; 22.06.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.

person AlexSavAlexandrov    schedule 21.09.2016

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

person StefanE    schedule 27.09.2011