3

I've got a TListView and several controls on a form representing data. When the selected item in the TListView changes, I want to validate the data and save it back to the backing store before changing to display the new record. But there doesn't appear to be any event handler to hook into. Turns out that the one that looks obvious, OnChanging, which even includes a way to abort the change, isn't about changing your selection at all; it's about editing the current item.

Is there any way I can do validation before changing the current selection on a TListView?

Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
  • You're wrong about `OnChanging`, setting 'false' to 'AllowChange' prevents item selection change. It wraps `LVN_ITEMCHANGING` and one of the changes it responds to is `LVIF_STATE` (e.g. selected).. – Sertac Akyuz Feb 10 '14 at 19:45
  • @SertacAkyuz: Unfortunately, `LVN_ITEMCHANGING` gets sent twice, making the validation run twice if you do it this way. This can be problematic if failing validation displays a message to the user, because there's no way to tell, inside the event handler, if you're in the first or the second run. – Mason Wheeler Feb 10 '14 at 22:51
  • With my tests there's only one satisfying the condition `Item<>ListView.Selected`, however it still may not suit you since it seems to allow to change the 'selected' anyway: to 'nil'. – Sertac Akyuz Feb 10 '14 at 23:40

1 Answers1

2

The event you are looking for is OnSelectItem. It fires once for the item being de-selected, and again for the item being selected.

procedure SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);

Here, Sender is the list view control, Item is the item being selected or de-selected, and Selected indicates whether this is selection or de-selection.

If you want to block selection change then OnChanging is indeed the event you need. Check the Change parameter. It has value ctState when the selection is changing. Set the AllowChange parameter to False to block the change.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Aha! I saw that event, but in the documentation it doesn't say anything about firing when an item is deselected, nor does it show the signature of the event handler, so I figured it would only fire on an item being selected. Thanks for pointing this out! – Mason Wheeler Feb 10 '14 at 19:36
  • The documentation I linked to have this text: *OnSelectItem is an event handler of type Vcl.ComCtrls.TLVSelectItemEvent.* The final part is a link to the description of the event type. So the signature of the event is documented. Always go for the latest docs, they are better: http://stackoverflow.com/questions/21403628/how-can-i-search-for-delphi-documentation – David Heffernan Feb 10 '14 at 19:39
  • OnChanging is less useful than it looks; see my comment up top. :( – Mason Wheeler Feb 10 '14 at 22:51
  • I'm trying to do the same thing as the OP, and as Mason pointed out, OnChanging and OnSelectItem fire multiple times when clicking on the items. What I have found is that even if AllowChange is set to false, the selected line still changed to be the new one. – SiBrit Jun 11 '14 at 05:21