最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

listview - How to use Checkboxes in TListView (OwnerData True) in Delphi - Stack Overflow

matteradmin7PV0评论

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;
Post a comment

comment list (0)

  1. No comments so far