Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Отображение и обработка иконки удаления в TVirtualStringTree при наведении или выборе узла

Delphi , Компоненты и Классы , TTreeView

 

Введение

TVirtualStringTree — это мощный компонент для отображения иерархических данных в Delphi, предоставляющий широкие возможности кастомизации. Одним из востребованных сценариев является добавление кнопки или иконки удаления для узлов, которая становится видимой только при наведении курсора или выборе строки. В этой статье мы рассмотрим, как реализовать такую функциональность.

Подготовка компонента

Для начала необходимо настроить TVirtualStringTree так, чтобы он поддерживал отрисовку дополнительных элементов управления в ячейках.

procedure TForm1.FormCreate(Sender: TObject);
begin
  VirtualStringTree1.NodeDataSize := SizeOf(TMyNodeData); // Указываем размер данных узла
  VirtualStringTree1.TreeOptions.PaintOptions := VirtualStringTree1.TreeOptions.PaintOptions 
    + [toShowButtons, toShowRoot, toShowTreeLines, toThemeAware, toHideFocusRect];
  VirtualStringTree1.TreeOptions.SelectionOptions := VirtualStringTree1.TreeOptions.SelectionOptions 
    + [toFullRowSelect];
  VirtualStringTree1.OnGetText := VirtualStringTree1GetText;
  VirtualStringTree1.OnGetImageIndex := VirtualStringTree1GetImageIndex;
  VirtualStringTree1.OnMouseMove := VirtualStringTree1MouseMove;
  VirtualStringTree1.OnMouseLeave := VirtualStringTree1MouseLeave;
  VirtualStringTree1.OnBeforeCellPaint := VirtualStringTree1BeforeCellPaint;
end;

Отрисовка иконки удаления

Для отображения иконки удаления при наведении или выборе узла воспользуемся событием OnBeforeCellPaint.

procedure TForm1.VirtualStringTree1BeforeCellPaint(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
var
  DeleteButtonRect: TRect;
  IsHot: Boolean;
begin
  if Column = 0 then // Иконка удаления будет в первой колонке
  begin
    IsHot := (Node = Sender.HotNode) or (vsSelected in Node.States);

    if IsHot then
    begin
      DeleteButtonRect := Rect(
        CellRect.Right - 20, 
        CellRect.Top + 2, 
        CellRect.Right - 4, 
        CellRect.Bottom - 2
      );

      // Рисуем иконку удаления (можно использовать TImageList или системную иконку)
      TargetCanvas.Brush.Color := clBtnFace;
      TargetCanvas.FillRect(DeleteButtonRect);
      TargetCanvas.Pen.Color := clRed;
      TargetCanvas.Rectangle(DeleteButtonRect);
      TargetCanvas.TextOut(DeleteButtonRect.Left + 4, DeleteButtonRect.Top + 2, 'X');
    end;
  end;
end;

Обработка клика по иконке

Чтобы обработать клик по иконке удаления, используем событие OnMouseDown:

procedure TForm1.VirtualStringTree1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Node: PVirtualNode;
  HitInfo: THitInfo;
  DeleteButtonRect: TRect;
begin
  if Button = mbLeft then
  begin
    Sender.GetHitTestInfoAt(X, Y, True, HitInfo);
    Node := HitInfo.HitNode;

    if Assigned(Node) and (HitInfo.HitColumn = 0) then
    begin
      DeleteButtonRect := Rect(
        Sender.Header.Columns[0].Width - 20, 
        Sender.GetNodeRect(Node).Top + 2, 
        Sender.Header.Columns[0].Width - 4, 
        Sender.GetNodeRect(Node).Bottom - 2
      );

      if PtInRect(DeleteButtonRect, Point(X, Y)) then
      begin
        // Удаляем узел
        Sender.DeleteNode(Node);
      end;
    end;
  end;
end;

Улучшение UX: анимация и подсказки

Для лучшего пользовательского опыта можно добавить:

  1. Подсказку при наведении на иконку
procedure TForm1.VirtualStringTree1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  Node: PVirtualNode;
  HitInfo: THitInfo;
begin
  Sender.GetHitTestInfoAt(X, Y, True, HitInfo);
  Node := HitInfo.HitNode;

  if Assigned(Node) and (HitInfo.HitColumn = 0) then
  begin
    if IsPointOverDeleteButton(Sender, X, Y) then
      ShowMessage('Удалить узел')
    else
      HideMessage();
  end;
end;
  1. Плавное появление иконки (используя AlphaBlend или анимацию через TAnimation)

Альтернативное решение: использование TVTHeaderPopupMenu

Если необходимо реализовать удаление через контекстное меню, можно использовать стандартный механизм TVirtualStringTree:

procedure TForm1.VirtualStringTree1PopupHeader(Sender: TObject;
  HitInfo: TVTHeaderHitInfo; const P: TPoint; var Result: Boolean);
begin
  if HitInfo.Column = 0 then
  begin
    PopupMenu1.Popup(P.X, P.Y);
    Result := True;
  end;
end;

Заключение

Реализация иконки удаления в TVirtualStringTree требует комбинации событий отрисовки и обработки мыши. Предложенный подход позволяет гибко настраивать внешний вид и поведение компонента. Для более сложных сценариев можно использовать дополнительные библиотеки, такие как VirtualTreeView-Styles, или расширить функционал через наследование.

Пример кода можно скачать по ссылке (если применимо).

Оптимизируйте ваш UI с TVirtualStringTree и делайте интерфейсы удобнее!

Создано по материалам из источника по ссылке.

Реализация отображения и обработки иконки удаления в TVirtualStringTree при наведении или выборе узла с использованием событий отрисовки и мыши.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: TTreeView ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-07-08 23:18:10/0.0065221786499023/0