В статье мы рассмотрим проблему замедления и мерцания списка, созданного с помощью TScrollBox и TPanel в качестве контейнера для каждого элемента. Мы исследуем альтернативы TPanel на основе TGraphicControl для улучшения производительности.
Проблема и контекст
Разработчик столкнулся с проблемой замедления и мерцания списка, содержащего множество контролов (TLabel, TImage, TShape), когда использовал TPanel в качестве контейнера для каждого элемента. При добавлении около 100 элементов список становился медленным и начинало появляться мерцание. Разработчик искал альтернативу TPanel на основе TGraphicControl для повышения производительности.
Альтернативные ответы и комментарии
В обсуждении были предложены несколько альтернативных решений:
Использование TGraphicControl с виртуальными объектами: Можно создать наследник TGraphicControl, который будет использовать виртуальные объекты (слои). При этом список определений виртуальных объектов (размер, положение, текст, форма, ...) будет храниться отдельно, и отображаться на оффскрин-битмапе при изменении любых определений. Остальное будет сводиться к копированию оффскрин-битмапа.
Использование TFrame вместо TScrollBox: Некоторые пользователи предложили использовать TFrame вместо TScrollBox. Один из них сообщал, что имеет TFrame с почти 1000 контролами, которые скролятся хорошо. Он также упомянул, что разделяет TFrame на секции с помощью TGroupBoxes.
Создание только видимых контролов: Было предложено создавать только те контролы, которые будут видимы, и освобождать те, которые выходят за пределы видимости. Это может потребовать существенной переработки дизайна.
Отключение контейнеров: Некоторые пользователи задались вопросом, почему вообще нужны контейнеры. Без них может быть сложнее выровнять и отсортировать элементы, но это, возможно, лучшее решение для ускорения списка.
Использование DoubleBuffered: Один из пользователей предложил установить Form.DoubleBuffered := True для предотвращения мерцания. Однако, это может привести к другим проблемам, и обычно лучше нарисовать все правильно в первый раз.
Использование LayoutControl от DevExpress: Один из пользователей упомянул, что LayoutControl от DevExpress может содержать более 50 контролов.
Подтвержденный ответ
В конечном итоге разработчик нашел решение, которое заключалось в использовании TPaintBox для каждой строки и рисовании с помощью канвы, как было предложено TLama. Это существенно ускорило список и позволило добавлять более 1000 элементов без замедления или мерцания.
Пример кода на Object Pascal (Delphi)
Ниже приведен пример кода, демонстрирующий использование TPaintBox для рисования списка без использования контейнеров:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
PaintBox1: TPaintBox;
procedure FormCreate(Sender: TObject);
private
FItems: TArray<string>;
procedure DrawItems(ACanvas: TCanvas);
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
FItems := TArray.Create('Item1', 'Item2', 'Item3', 'Item4', 'Item5'); // Замените на реальные данные
PaintBox1.Width := 200;
PaintBox1.Height := 300;
PaintBox1.Canvas.Brush.Color := clWhite;
PaintBox1.Canvas.FillRect(PaintBox1.ClientRect);
DrawItems(PaintBox1.Canvas);
end;
procedure TForm1.DrawItems(ACanvas: TCanvas);
var
I, Y: Integer;
begin
Y := 0;
for I := Low(FItems) to High(FItems) do
begin
ACanvas.TextOut(0, Y, FItems[I]);
Y := Y + 20;
end;
end;
end.
В данном примере мы используем TPaintBox для рисования списка элементов в процедуре DrawItems. Каждый элемент рисуется с помощью TextOut, а позиция Y обновляется после каждого элемента для обеспечения вертикального смещения. Это позволяет нам избежать использования контейнеров и ускоряет список.
В статье рассматривается проблема замедления и мерцания списка, созданного с помощью TScrollBox и TPanel в качестве контейнера для каждого элемента, и исследуются альтернативы TPanel на основе TGraphicControl для улучшения производительности.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.