问题描述
是否可以在 TListView
中修复子项目
图像的绘制,以使它们不会被切除如图所示,在左侧?
Is it possible to fix the drawing of subitem
images in a TListView
so that they are not cut-off on the left hand side as shown in the image?
推荐答案
好吧, Pieter van Wyk ,我做了一个最小的示例,说明如何所有者绘制 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.
答案已被重写。为了减小答案的大小,我删除了未使用和错误的部分。以前的版本可能在问题编辑的历史记录中找到。
下面的图片代表新代码的工作。
选定的行。
所选行上的图像周围带有白色。这不是错误-它是带有这种填充的源图像。
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;
要应用此代码,您必须激活 OwnerDraw
属性。
To apply this code you must activate OwnerDraw
property.
请参阅此,该属性导致 docs.embarcadero
。我还想显示来自上面链接的报价:
See this TListView.OwnerDraw Property that leads to docs.embarcadero
. I also would like to show a quote from a link above:
PS
之后的列调整大小后,可能会出现一些图形伪像
-只是尝试以隐藏(最小列大小)和显示图像(任何超出
P.S.
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.
PSS
绘制子项目的文本我把功课留给你;)
P.S.S.
Drawing a text of sub-items I leave to you as a homework ;)
这篇关于在TListView中将子项目图像居中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!