admin管理员组

文章数量:1023758

I am trying to implement checkboxes in a TListView component with OwnerData=True in Delphi 10.3.3 VCL project.

Here's a minimal example of what I have tried so far:

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView1.ViewStyle := vsReport;
  ListView1.OwnerData := True;
  ListView1.Checkboxes := True;

  // MyData with some initial data
end;

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
  Item.Caption := 'Item ' + IntToStr(Item.Index + 1);
  Item.Checked := MyData[Item.Index].FChecked;
end;

However, it doesn't display checkboxes.

Is there a recommended approach or workaround to handle this effectively? Any code examples or guidance would be greatly appreciated!

I am trying to implement checkboxes in a TListView component with OwnerData=True in Delphi 10.3.3 VCL project.

Here's a minimal example of what I have tried so far:

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView1.ViewStyle := vsReport;
  ListView1.OwnerData := True;
  ListView1.Checkboxes := True;

  // MyData with some initial data
end;

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
  Item.Caption := 'Item ' + IntToStr(Item.Index + 1);
  Item.Checked := MyData[Item.Index].FChecked;
end;

However, it doesn't display checkboxes.

Is there a recommended approach or workaround to handle this effectively? Any code examples or guidance would be greatly appreciated!

Share Improve this question edited Nov 18, 2024 at 21:28 Xel Naga asked Nov 18, 2024 at 18:18 Xel NagaXel Naga 9961 gold badge14 silver badges38 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 3

The CheckBoxes feature is implemented using an internal state image list, however the underlying Win32 ListView control does not support state images in virtual mode. So, you would need to either:

  • owner-draw the list items to manually draw check boxes on them.

  • put the desired check box images into a TImageList that is assigned to the ListView's SmallImages property, and then set the TListItem.ImageIndex property as needed in your TListView.OnData handler.

See: Using tListView with OwnerData and Checkboxes

This issue seems to have been discussed multiple times, but no one has shared a complete code solution. Thanks to Remy's answer, I was finally able to write the full code, and it works!

ListView properties:

ViewStyle = vsReport
OwnerData = True
OwnerDraw = False
CheckBoxes = False
StateImages = VirtualImageList1

Code:

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
  Item.Caption := MyData[Item.Index].FColumn1;
  Item.SubItems.Add(MyData[Item.Index].FColumn2);
  if MyData[Item.Index].FChecked then
  begin
    Item.Checked:=True;
    Item.StateIndex:=1;
  end else
  begin
    Item.Checked:=False;
    Item.StateIndex:=0;
  end;
end;

procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  HitTestInfo: THitTests;
  Item: TListItem;
begin
  HitTestInfo := ListView1.GetHitTestInfoAt(X, Y);
  if htOnStateIcon in HitTestInfo then
  begin
    Item := ListView1.GetItemAt(X, Y);
    if Assigned(Item) then
    begin
      MyData[Item.Index].FChecked := not MyData[Item.Index].FChecked;
      ListView1.Items[Item.Index].Update;
    end;
  end;
end;

procedure TForm1.ListView1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if key=32 then // space key
  begin
    if ListView1.ItemIndex>-1 then
    begin
      MyData[ListView1.ItemIndex].FChecked := not MyData[ListView1.ItemIndex].FChecked;
      ListView1.Items[ListView1.ItemIndex].Update;
    end;
  end;
end;

I am trying to implement checkboxes in a TListView component with OwnerData=True in Delphi 10.3.3 VCL project.

Here's a minimal example of what I have tried so far:

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView1.ViewStyle := vsReport;
  ListView1.OwnerData := True;
  ListView1.Checkboxes := True;

  // MyData with some initial data
end;

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
  Item.Caption := 'Item ' + IntToStr(Item.Index + 1);
  Item.Checked := MyData[Item.Index].FChecked;
end;

However, it doesn't display checkboxes.

Is there a recommended approach or workaround to handle this effectively? Any code examples or guidance would be greatly appreciated!

I am trying to implement checkboxes in a TListView component with OwnerData=True in Delphi 10.3.3 VCL project.

Here's a minimal example of what I have tried so far:

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView1.ViewStyle := vsReport;
  ListView1.OwnerData := True;
  ListView1.Checkboxes := True;

  // MyData with some initial data
end;

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
  Item.Caption := 'Item ' + IntToStr(Item.Index + 1);
  Item.Checked := MyData[Item.Index].FChecked;
end;

However, it doesn't display checkboxes.

Is there a recommended approach or workaround to handle this effectively? Any code examples or guidance would be greatly appreciated!

Share Improve this question edited Nov 18, 2024 at 21:28 Xel Naga asked Nov 18, 2024 at 18:18 Xel NagaXel Naga 9961 gold badge14 silver badges38 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 3

The CheckBoxes feature is implemented using an internal state image list, however the underlying Win32 ListView control does not support state images in virtual mode. So, you would need to either:

  • owner-draw the list items to manually draw check boxes on them.

  • put the desired check box images into a TImageList that is assigned to the ListView's SmallImages property, and then set the TListItem.ImageIndex property as needed in your TListView.OnData handler.

See: Using tListView with OwnerData and Checkboxes

This issue seems to have been discussed multiple times, but no one has shared a complete code solution. Thanks to Remy's answer, I was finally able to write the full code, and it works!

ListView properties:

ViewStyle = vsReport
OwnerData = True
OwnerDraw = False
CheckBoxes = False
StateImages = VirtualImageList1

Code:

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
  Item.Caption := MyData[Item.Index].FColumn1;
  Item.SubItems.Add(MyData[Item.Index].FColumn2);
  if MyData[Item.Index].FChecked then
  begin
    Item.Checked:=True;
    Item.StateIndex:=1;
  end else
  begin
    Item.Checked:=False;
    Item.StateIndex:=0;
  end;
end;

procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  HitTestInfo: THitTests;
  Item: TListItem;
begin
  HitTestInfo := ListView1.GetHitTestInfoAt(X, Y);
  if htOnStateIcon in HitTestInfo then
  begin
    Item := ListView1.GetItemAt(X, Y);
    if Assigned(Item) then
    begin
      MyData[Item.Index].FChecked := not MyData[Item.Index].FChecked;
      ListView1.Items[Item.Index].Update;
    end;
  end;
end;

procedure TForm1.ListView1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if key=32 then // space key
  begin
    if ListView1.ItemIndex>-1 then
    begin
      MyData[ListView1.ItemIndex].FChecked := not MyData[ListView1.ItemIndex].FChecked;
      ListView1.Items[ListView1.ItemIndex].Update;
    end;
  end;
end;

本文标签: listviewHow to use Checkboxes in TListView (OwnerData True) in DelphiStack Overflow