ListView’s OnCheckboxClick event
Unfortunately, the TListView object does not have a specific event fired, when the Checked
state changes for a TListItem (an item in the ListView). If you need to react in such situation, you have to mimic this behaviour yourself. Here are some tips on this.
Every Delphi’s Guru will probably think about subclassing and catching windows messages here. If you’re one of them — at delphi.about.com you’ll find an example. But, there’s an easier way to achieve the same.
I crafted it together out of two separate solutions — DelphiPages.com forum and Delphi forum at cjcsoft.net.
All you have to do is to catch OnMouseDown
or OnMouseUp
and use two methods of TListView
there — GetHitTestInfoAt
and GetItemAt
. Here is full example:
procedure TMainForm.ListViewMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
ht: THitTests;
Item: TListItem;
begin
ht := (Sender as TCustomListView).GetHitTestInfoAt(X, Y);
if htOnStateIcon in ht then
begin
Item := (Sender as TCustomListView).GetItemAt(X, Y);
ShowMessage('OnCheckboxClick fired on item "' + Item.Caption + '"');
end;
end;
If, for any reason, you need to use OnClick
event (which does not provides X
and Y
variables), you still can do this, but you need to add these lines to your code:
var
P: TPoint;
begin
GetCursorPos(P);
P := (Sender as TCustomListView).ScreenToClient(P);
and then change:
ht := (Sender as TCustomListView).GetHitTestInfoAt(X, Y);
with:
ht := (Sender as TCustomListView).GetHitTestInfoAt(P.X, P.Y);
Leave rest untoched and your code should work the same even in OnClick
event.
This example uses (Sender as TCustomListView)
construction, because I use the same procedure as OnMouseUp
even handler for more than one TListView
. If you only need to use this solution for one ListView, you can use its name directly (i.e. ListView1.GetItemAt
assuming that it’s name is ListView1
).
Of course, this solutions mimic OnCheckboxClick
, not OnCheckBoxStateChange
. This means, that with it, you can react only on user clicking checbox. You can’t react this way on checkbox changing state by programical meanings — i.e. changing TListItem.Checked
property from your code.