Но свойство Checkbox поддерживает только режимы vsList и vsReport ...
Это неверно.Вы просматриваете документацию VCL , в которой говорится
Установите Флажки в значение true, чтобы флажки появлялись рядом с элементами списка, когда ViewStyle равен vsList или vsReport....
Это устаревшая информация.См. документацию для собственного элемента управления:
Версия 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: артефакты рисования должны быть предметом другого вопроса.