Ну, Питер ван Вик , я сделал минимальный пример того, как вы можете нарисовать владельцем компонент TListView
, чтобы центрировать изображения в подэлементах.
Ответ был переписан. Чтобы уменьшить размер ответа, я удалил неиспользуемые и неправильные части. Предыдущие версии можно найти в истории редактирования вопроса.
Изображение ниже представляет работу нового кода.
Одна оранжевая строка - выбранная строка.
![enter image description here](https://i.stack.imgur.com/BZabT.png)
Изображения в выбранном ряду имеют белый цвет вокруг него. Это не ошибка - это исходное изображение с такой заливкой.
Существует код, позволяющий сделать то же самое, что и на картинке:
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.
Написание текста подпунктов я оставляю вам как домашнее задание;)