listview - 具有对 vsIcon 和 vsSmallIcon 的复选框支持的虚拟 ListView?
问题描述
我在 Delphi 中使用 ListView。我将 OwnerData 属性设置为 true,以便在 OnData 事件中提供项目的数据。
此外,我想为列表视图的每个项目添加一个复选框。但是 Checkbox 属性只支持 vsList 和 vsReport 模式,不支持 vsIcon 和 vsSmalicon。有解决方法吗?或者是否有任何现成的支持此类功能的 3rd 方 VCL?
解决方案
但是 Checkbox 属性只支持 vsList 和 vsReport 模式...
这是不正确的。您正在查看 VCL文档,其中指出
当 ViewStyle 为 vsList 或 vsReport 时,将Checkboxes设置为 true 以使复选框显示在列表项旁边。...
这是过时的信息。请参阅本机控件的文档:
版本 6.00 及更高版本复选框在所有列表视图模式下可见且有效,除了 ComCtl32.dll 版本 6 中引入的平铺视图模式。 ...
实际上,如果您在其中一种图标模式下对常规TListView
控件进行尝试,您会发现复选框没有问题。
但是,这对您没有帮助。在这方面,您的问题格式不正确,它假设Checkboxes
在具有虚拟列表视图控件的列表和报告模式下工作正常。事实并非如此。
Checked
当您可以在列表项上使用该属性时,复选框是很好的选择。在虚拟列表视图控件中没有可以检查的项目。我从LVM_SETITEMCOUNT
消息中引用:
如果列表视图控件是在没有LVS_OWNERDATA样式的情况下创建的,则发送此消息会导致控件为指定数量的项目分配其内部数据结构。...
...
如果列表视图控件是使用LVS_OWNERDATA样式(虚拟列表视图)创建的,则发送此消息会设置控件包含的虚拟项目数。
所有控件都知道有那么多项目,没有每个项目的存储。VCL 反映 API 控件:当您请求一个项目并且您的控件已OwnerData
设置时,OnData
会在临时项目上调用事件处理程序以反映该项目的属性。
在虚拟列表视图中,您可以使用状态图像来管理检查。引用文档:
...您可以使用状态图像(例如选中和清除复选框)来指示应用程序定义的项目状态。状态图像以图标视图、小图标视图、列表视图和报告视图显示。
您将在下面找到一个基本实现,它将项目状态信息保存在一个单独的数组中。要运行它,请创建一个空白的新表单,OnCreate
为该表单创建一个处理程序并粘贴代码。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ImgList;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
FListView: TListView;
FListViewCheckStateArray: array of 0..1;
procedure ListViewData(Sender: TObject; Item: TListItem);
procedure ListViewMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
Bmp: TBitmap;
begin
FListView := TListView.Create(Self);
FListView.Parent := Self;
FListView.Align := alClient;
FListView.OwnerData := True;
FListView.ViewStyle := vsSmallIcon;
FListView.StateImages := TImageList.Create(Self);
Bmp := TBitmap.Create;
Bmp.PixelFormat := pf32bit;
Bmp.SetSize(16, 16);
DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
DFCS_BUTTONCHECK);
FListView.StateImages.Add(Bmp, nil);
DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
DFCS_BUTTONCHECK or DFCS_CHECKED);
FListView.StateImages.Add(Bmp, nil);
Bmp.Free;
FListView.Items.Count := 257;
SetLength(FListViewCheckStateArray, FListView.Items.Count);
FListView.OnData := ListViewData;
FListView.OnMouseDown := ListViewMouseDown;
end;
procedure TForm1.ListViewData(Sender: TObject; Item: TListItem);
begin
Item.Caption := Format('This is item %.2d', [Item.Index]);
Item.StateIndex := FListViewCheckStateArray[Item.Index];
end;
procedure TForm1.ListViewMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Item: TListItem;
begin
if (Button = mbLeft) and
(htOnStateIcon in FListView.GetHitTestInfoAt(X, Y)) then begin
Item := FListView.GetItemAt(X, Y);
Assert(Assigned(Item));
FListViewCheckStateArray[Item.Index] :=
Ord(not Boolean(FListViewCheckStateArray[Item.Index]));
FListView.UpdateItems(Item.Index, Item.Index);
end;
end;
end.
PS:绘图工件应该是另一个问题的主题。
推荐阅读
- logging - LoggerMessage 字符串插值不起作用 - NLOG 和 Azure 表存储
- date - 带有日期变量的 SSIS For 循环容器
- mysql - MySQL导入脚本添加额外的行?
- android - 使用多个自定义首选项会搞砸、布局、首选项标题和共享首选项值
- javascript - 获取 javascript - 未捕获的类型错误:
- definition - C#语言规范说明:6.2.4 显式引用转换
- cpu-architecture - gem5 简单配置脚本上的“连续 SC 失败”
- elasticsearch - Logstash 无法启动 - 错误:此时 tibrvnativesd.jar 出乎意料
- visual-studio-code - 摩卡在 npm 测试中没有失败
- python - 如何将 python 连接到 Azure Cloud 并创建 azure 数据工厂