[英]Center subitem images in a TListView
Well, Pieter van Wyk , I did minimal example of how you can owner-draw your TListView
component in order to center images in sub-items. 好吧, Pieter van Wyk ,我做了一个最小的示例,说明如何所有者绘制TListView
组件以将图像居中于子项中。
Answer has been rewritten. 答案已被重写。 In order to decrease size of answer I had deleted unused and wrong parts. 为了减小答案的大小,我删除了未使用和错误的部分。 Previous versions may be found in history of question editing. 以前的版本可以在问题编辑的历史记录中找到。
Picture below represents work of the new code. 下图显示了新代码的工作。
One orange row is a selected row. 橙色行是选定的行。
Images on selected row have white color around it. 所选行上的图像周围带有白色。 It is not a bug - it is a source image with such fill. 这不是错误-它是具有此类填充的源图像。
There is the code that allows to do the same thing as on the picture: 有一些代码可以执行与图片相同的操作:
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;
To apply this code you must activate OwnerDraw
property . 要应用此代码,必须激活OwnerDraw
属性 。
See this TListView.OwnerDraw Property that leads to docs.embarcadero
. 请参见导致docs.embarcadero
TListView.OwnerDraw属性 。 I also would like to show a quote from a link above: 我还想显示来自上面链接的报价:
Set OwnerDraw to true to allow the list view to receive the OnDrawItem event instead of the default rendering of list items. 将OwnerDraw设置为true以允许列表视图接收OnDrawItem事件,而不是列表项的默认呈现。
PS PS
After column has been resized, there could be some graphical artifacts
- just try to resize column in a way to hide (minimal possible size of column) and show image (any size of column that will exceeds size of associated image) and you will see what I meant. 调整列的大小后,可能会出现一些graphical artifacts
-只需尝试以隐藏(最小列的可能大小)和显示图像(任何超出关联图像大小的列的大小)的方式来调整列的大小,您将看到我的意思
PSS PSS
Drawing a text of sub-items I leave to you as a homework ;) 绘制子项目的文本,我留给您作为作业;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.