Изменение цвета фона строк в TVirtualStringTree при разных состояниях
В этом материале мы рассмотрим, как изменить цвет фона строк в TVirtualStringTree при разных состояниях, таких как выделенная и невыделенная. Мы также рассмотрим, как применить разные цвета для разных выделенных строк и как создать плавный переход цвета для строк с ограниченной продолжительностью.
TVirtualStringTree и изменение цвета фона строк
TVirtualStringTree — это высокопроизводительное дерево с поддержкой виртуализации, которое позволяет отображать большие количества данных без замедления работы приложения. Одним из часто задаваемых вопросов является изменение цвета фона строк tanto в selected as in non-selected states.
Вопрос:
Я использую последнюю версию VirtualTreeView и пытаюсь изменить цвет фона всей строки TVirtualStringTree tanto в selected как в non-selected states. Существует много похожих вопросов с разными ответами, но ни один из них не подходит идеально. Во всех них просто пишется обработчик, который включает в себя фрагмент кода, подобный этому:
OnBeforeCellPaint работает только в невыделенном состоянии строки.
OnDrawText работает в обоих состояниях, но вся строка выглядит разделенной пробелами между ячейками.
OnBeforeItemErased влияет на всю строку, но опять же, если она не в выделенном состоянии.
Рисование в некоторых других обработчиках либо повторно перерисовывается автоматически, либо требует полной ручной отрисовки, что кажется избыточным для такой простой задачи.
Я не смог найти простой способ сделать это, учитывая дополнительные условия:
Строка должна оставаться в выделенном состоянии, так как дерево может находиться в режиме MultiSelected (включено toMultiSelect).
Цвета выделенного и невыделенного состояний строки, а также разных выделенных строк могут отличаться.
Лучшее, что я смог сделать, — это написать обработчик на OnDrawText events:
Дерево создается с помощью массива записей (сильно упрощенный вариант):
type
TJob = record
Running: Boolean; // job is stopped or running
MaxDuration: Integer; // 0 - infinite, or seconds
Start: TDateTime; // The job start time
end;
Если работа остановлена, ее строка должна вести себя по умолчанию в дереве.
Если работа запущена и бесконечна, она должна быть окрашена, например, в зеленый цвет, если выделена — в темно-зеленый.
Если работа запущена и имеет ограниченную продолжительность, ее строка должна иметь плавный переход цвета от зеленого к красному, который постоянно меняется по мере приближения к сроку. Если выделено, цвет должен быть ярче.
Решение
Чтобы изменить цвет фона строк в TVirtualStringTree при разных состояниях, вы можете использовать обработчик OnBeforeCellPaint для невыделенной строки и свойство Colors.FocusedSelectionColor для выделенной строки. Вот пример кода, который демонстрирует, как это сделать:
procedure TForm1.VirtualStringTree1BeforeCellPaint(Sender: TObject; Node: PVirtualNode; TargetCanvas: TCanvas;
CellRect: TRect; CellState: TVirtualCellState);
begin
if not (vsSelected in Node.States) then
begin
// Изменить цвет фона для невыделенной строки
TargetCanvas.Brush.Color := clYellow;
TargetCanvas.FillRect(CellRect);
end;
end;
procedure TForm1.VirtualStringTree1BeforeSelect(Sender: TObject; Node: PVirtualNode; Selected: Boolean);
begin
if Selected then
begin
// Изменить цвет фона для выделенной строки
VirtualStringTree1.Colors.FocusedSelectionColor := clGreen;
end;
end;
В этом примере мы используем обработчик OnBeforeCellPaint для изменения цвета фона невыделенной строки. Мы также используем обработчик OnBeforeSelect для изменения цвета фона выделенной строки с помощью свойства Colors.FocusedSelectionColor.
Применение разных цветов для разных выделенных строк
Чтобы применить разные цвета для разных выделенных строк, вы можете использовать свойство Node.Color для каждой строки. Например:
procedure TForm1.VirtualStringTree1BeforeSelect(Sender: TObject; Node: PVirtualNode; Selected: Boolean);
begin
if Selected then
begin
// Применить разный цвет для разных выделенных строк
case Node.Index mod 3 of
0: Node.Color := clGreen;
1: Node.Color := clBlue;
2: Node.Color := clRed;
end;
end;
end;
В этом примере мы используем обработчик OnBeforeSelect для изменения цвета фона выделенной строки в зависимости от индекса строки. Мы используем оператор case для применения разных цветов для разных строк в зависимости от остатка от деления индекса строки на 3.
Создание плавного перехода цвета для строк с ограниченной продолжительностью
Чтобы создать плавный переход цвета для строк с ограниченной продолжительностью, вы можете использовать таймер для обновления цвета фона строки по мере приближения к сроку окончания. Вот пример кода, который демонстрирует, как это сделать:
type
TJob = record
Running: Boolean; // job is stopped or running
MaxDuration: Integer; // 0 - infinite, or seconds
Start: TDateTime; // The job start time
Color: TColor; // Color for the row
end;
procedure TForm1.VirtualStringTree1BeforeCellPaint(Sender: TObject; Node: PVirtualNode; TargetCanvas: TCanvas;
CellRect: TRect; CellState: TVirtualCellState);
begin
if not (vsSelected in Node.States) then
begin
// Изменить цвет фона для невыделенной строки в зависимости от срока окончания
with TJob(Node.Data) do
begin
if Running and MaxDuration > 0 then
begin
// Рассчитать процент окончания срока
var ElapsedTime: Double;
ElapsedTime := (Now - Start).InSeconds;
var Percentage: Double;
Percentage := ElapsedTime / MaxDuration;
// Изменить цвет фона в зависимости от процента окончания срока
var Red, Green, Blue: Integer;
Red := 255 * (1 - Percentage);
Green := 255 * Percentage;
Blue := 0;
Color := RGB(Red, Green, Blue);
TargetCanvas.Brush.Color := Color;
TargetCanvas.FillRect(CellRect);
end;
end;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
// Обновить цвета фона строк с ограниченной продолжительностью
for var Node in VirtualStringTree1.Nodes do
begin
with TJob(Node.Data) do
begin
if Running and MaxDuration > 0 then
begin
// Рассчитать процент окончания срока
var ElapsedTime: Double;
ElapsedTime := (Now - Start).InSeconds;
var Percentage: Double;
Percentage := ElapsedTime / MaxDuration;
// Изменить цвет фона в зависимости от процента окончания срока
var Red, Green, Blue: Integer;
Red := 255 * (1 - Percentage);
Green := 255 * Percentage;
Blue := 0;
Color := RGB(Red, Green, Blue);
// Перерисовать строку
VirtualStringTree1.InvalidateNode(Node);
end;
end;
end;
end;
В этом примере мы используем обработчик OnBeforeCellPaint для изменения цвета фона невыделенной строки в зависимости от срока окончания. Мы используем таймер для обновления цвета фона строки по мере приближения к сроку окончания. В обработчике таймера мы перебираем все строки в дереве и обновляем их цвет в зависимости от процента окончания срока. Мы также перерисовываем каждую строку после изменения цвета фона.
В этом материале рассматривается, как изменить цвет фона строк в TVirtualStringTree в зависимости от различных состояний, таких как выделенная и невыделенная, а также применить разные цвета для разных выделенных строк и создать плавный переход цвета для с
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.