Виртуальный ListView с поддержкой флажков для vsIcon и vsSmallIcon? - PullRequest
0 голосов
/ 19 ноября 2018

Я использую ListView в Delphi.Я установил для свойства OwnerData значение true, чтобы предоставить данные элемента в событии OnData.

Кроме того, я хочу добавить флажок для каждого элемента представления списка.Но свойство Checkbox поддерживает только режимы vsList и vsReport, но не vsIcon и vsSmallicon.Есть ли обходной путь для этого?Или есть какой-либо готовый сторонний VCL, поддерживающий такую ​​функцию?

1 Ответ

0 голосов
/ 19 ноября 2018

Но свойство 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: артефакты рисования должны быть предметом другого вопроса.

...