【发布时间】:2018-10-28 04:04:48
【问题描述】:
我正在使用 Delphi XE3 并希望实现 Windows 缩略图样式以通过 TListView 控件显示图像列表。
我需要的如下:
图像显示为缩略图样式,每张图像下方都有一个标题。当我点击图片时,图片连同标题将显示为选中...
为了提高性能,我不想预先将所有图像加载到图像列表中,而是在图像要显示时加载。因此,我正在考虑使用 OnCustomDrawItem 和 OnAdvancedCustomDrawItem。
下面是我计划的一个非常简单的版本(我将列表视图的样式设置为vsIcon):
procedure TForm1.FormCreate(Sender: TObject);
var
ListItem1: TListItem;
begin
ListItem1 := ListView1.Items.Add;
ListItem1.Caption := 'Chrysanthemum';
end;
procedure TForm1.ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
var DefaultDraw: Boolean);
var
JPEG: TJPEGImage;
R: TRect;
begin
{
R := Item.DisplayRect(drBounds);
JPEG := TJPEGImage.Create;
JPEG.LoadFromFile('C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum (2).jpg');
Sender.Canvas.StretchDraw(R, JPEG);
}
end;
procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
var
JPEG: TJPEGImage;
R: TRect;
begin
R := Item.DisplayRect(drBounds);
JPEG := TJPEGImage.Create;
JPEG.LoadFromFile('C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum (2).jpg');
Sender.Canvas.StretchDraw(R, JPEG);
end;
但结果并不理想,如下:
我找不到设置每个图标大小的方法。 (所有图标都将具有相同的大小)。
我尝试将代码放在 OnCustomDrawItem 和 OnAdvancedCustomDrawItem 中。我无法弄清楚这两者之间有多大区别。 Advancedxxx 版本中唯一的主要区别在于,标题是可编辑的。我不明白为什么。
标题不显示在图像下方,而是显示在图像中间,这是不希望的。如何解决?
谢谢
【问题讨论】:
-
查看
OnDrawItem()事件的文档。有一条注释说:注意:列表视图接收其他几个自定义绘制事件,包括 OnCustomDraw、OnCustomDrawItem、OnCustomDrawSubItem、OnAdvancedCustomDraw、OnAdvancedCustomDrawItem 和 OnAdvancedCustomDrawSubItem。与 OnDrawItem 不同,这些其他事件的发生与 OwnerDraw 属性的值无关。 ... 所以,使用这些其他事件中的任何一个。 -
如果您想在
TListView中显示大量图像,请考虑在虚拟模式下使用它,将OwnerData属性设置为true。 Example of owner-drawing items in TListView. -
@Dima 有没有关于 TListView 所有者绘图的完整示例代码?您提供的链接使用 AdvancedCustomDrawItem,我检查了文档 docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/…,它说“要在其他阶段(例如在绘制列表项之后)增加默认绘图过程,请改用 OnAdvancedCustomDrawItem 事件。”所以看起来这个例子使用了错误的事件处理程序?
-
不,示例是正确的。如果您将使用
OnCustomDrawItem事件,您应该从头开始绘制项目,将DefaultDraw设置为false,否则您将在绘图上完成默认绘图。OnAdvancedCustomDrawItem事件允许您控制绘制阶段cdPrePaint和cdPostPaint。在我看来,所有者绘制TListView是一种更优雅的方式,对于这个简单的例子来说就足够了。但是是的,如果您要在绘图事件中进行重绘,最好使用OnCustomDrawItem事件,因为它发生之前 实际项目绘图。使用什么取决于您的需求。 -
我建议你看看this component。它可以将图像显示为标准
TListView(但它不具备后者的所有功能)。在您指定要在其中搜索的文件夹后,它会缓存图像。这东西值得一试。可能对于您的任务来说,它可能比使用标准TListView跳舞更有用。
标签: listview delphi delphi-xe3