我在Delphi中使用ListView。我将OwnerData属性设置为true,以便在OnData事件中提供该项的数据。
此外,我想为列表视图的每个项目添加一个复选框。但是Checkbox属性仅支持vsList和vsReport模式,不支持vsIcon和vsSmallicon。是否有解决方法?还是有任何支持此类功能的现成的第三方VCL?
答案 0 :(得分:4)
但是Checkbox属性仅支持vsList和vsReport模式...
那是不正确的。您正在查看状态为{p>的VCL documentation
将Checkboxes设置为true,以使复选框显示在列表旁边 ViewStyle为vsList或vsReport时的项目。 ...
这是过时的信息。有关原生控件,请参见documentation:
Version 6.00 and later复选框可见,所有复选框均可以使用 列表视图模式(ComCtl32.dll中引入的平铺视图模式除外) 版本6。...
实际上,如果您在其中一种图标模式下的常规TListView
控件上进行尝试,则会发现复选框没有问题。
但是那对您没有帮助。在这方面,您的问题格式不正确,它假设Checkboxes
在带有虚拟列表视图控件的列表和报告模式下可以正常工作。情况并非如此。
可以在列表项上使用Checked
属性时,复选框会很好。在虚拟列表视图控件中,没有可以检查的项目。我引用了LVM_SETITEMCOUNT
消息:
如果创建的列表视图控件没有LVS_OWNERDATA样式, 发送此消息会导致控件分配其内部数据 指定数量的项目的结构。 ...
...
如果列表视图控件是用LVS_OWNERDATA样式创建的( 虚拟列表视图),则发送此消息可设置 控件包含的项目。
所有控件都知道有很多项目,没有每项存储。 VCL反映了API控件:当您请求一个项目并且您的控件已设置OwnerData
时,会在一个临时项目上调用OnData
事件处理程序以反映该项目的属性。
在虚拟列表视图中,您可以使用状态图像来管理检查。引用documentation:
...您可以使用状态图像,例如选中和清除的复选框, 指示应用程序定义的项目状态。状态图像是 显示在图标视图,小图标视图,列表视图和报告视图中。
下面您将找到一个基本实现,该实现将项目状态信息保存在单独的数组中。要运行它,请创建一个空白的新表单,为该表单创建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:工件应该是另一个问题的主题。