Центрировать подэлемент изображения в TListView - PullRequest
0 голосов
/ 31 августа 2018

Можно ли исправить рисунок subitem изображений в TListView, чтобы они не обрезались с левой стороны, как показано на рисунке?
enter image description here

1 Ответ

0 голосов
/ 31 августа 2018

Ну, Питер ван Вик , я сделал минимальный пример того, как вы можете нарисовать владельцем компонент TListView, чтобы центрировать изображения в подэлементах.

Ответ был переписан. Чтобы уменьшить размер ответа, я удалил неиспользуемые и неправильные части. Предыдущие версии можно найти в истории редактирования вопроса.

Изображение ниже представляет работу нового кода.
Одна оранжевая строка - выбранная строка. enter image description here
Изображения в выбранном ряду имеют белый цвет вокруг него. Это не ошибка - это исходное изображение с такой заливкой.

Существует код, позволяющий сделать то же самое, что и на картинке:

procedure TForm1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem; Rect: TRect;
  State: TOwnerDrawState);
var
  Bmp: TBitmap;
  Image: TBitmap;
  R: TRect;
  CenterH: Integer;
  CenterV: Integer;
  ImageIndex: Integer;
  ItemWidth: Integer;
  i: Integer;
begin
  // Set initial legth of point at the end of which image will be drawn.  
  // Column 0 is a "fixed" column
  ItemWidth := Sender.Column[0].Width;
  R := Rect;

  Bmp := TBitmap.Create;
  try
    Image := TBitmap.Create;
    try
      Bmp.SetSize(R.Width, R.Height);

      // Make fill for item
      if Item.Selected then
        Bmp.Canvas.Brush.Color := clWebOrange
      else
        Bmp.Canvas.Brush.Color := clMoneyGreen;
      Bmp.Canvas.FillRect(Bmp.Canvas.ClipRect);

      // Output image associated with 'fixed' column
      TListView(Sender).SmallImages.GetBitmap(Item.ImageIndex, Image);
      CenterH := (Sender.Column[0].Width - Image.Width) div 2;
      CenterV := (R.Height - Image.Height) div 2;
      Bmp.Canvas.Draw(CenterH, CenterV, Image);

      // Output text
      Bmp.Canvas.TextOut(CenterH + Image.Width + 6, 6, Item.Caption);

      // Draw sub-items
      for i:=0 to Item.SubItems.Count - 1 do
        begin
          // Obtain index of image
          ImageIndex := Item.SubItemImages[i];

          // Get associated image
          TListView(Sender).SmallImages.GetBitmap(ImageIndex, Image);

          // Center image
          CenterH := (Sender.Column[i+1].Width - Image.Width) div 2;
          CenterV := (R.Height - Image.Height) div 2;

          // Output image
          Bmp.Canvas.Draw(ItemWidth + CenterH, CenterV, Image);

          // Increase point where image started to be drawn
          Inc(ItemWidth, Sender.Column[i+1].Width);
        end;

      // Draw ready item's image onto sender's canvas
      Sender.Canvas.Draw(R.Left, R.Top, Bmp);
    finally
      Image.Free;
    end;
  finally
    Bmp.Free;
  end;
end;

Чтобы применить этот код , необходимо активировать OwnerDraw свойство .

См. Это Свойство TListView.OwnerDraw , которое приводит к docs.embarcadero. Я также хотел бы показать цитату по ссылке выше:

Установите для OwnerDraw значение true, чтобы позволить представлению списка получать событие OnDrawItem вместо отображения элементов списка по умолчанию.

приписка
После изменения размера столбца может быть некоторое значение graphical artifacts - просто попробуйте изменить размер столбца таким образом, чтобы скрыть (минимально возможный размер столбца) и показать изображение (любой размер столбца, который будет превышать размер связанного изображения), и вы получите посмотри, что я имел в виду.

P.S.S.
Написание текста подпунктов я оставляю вам как домашнее задание;)

...