Jump to content
Incus J

TListView OnChange Event Doesn't Fire

Recommended Posts

I have an FMX project with a TListView control.  I need to detect when the user selects an item in the list.  There's no OnItemSelected event, but previously I used the control's OnChange event for this.  Since upgrading from 10.4 to 10.4.1 this no longer works and I'm seeing odd behaviour :

 

  • Click on any item in the listview - OnChange event does not trigger 😞
  • Select an item using the Up/Down arrow keys on the keyboard - OnChange event triggers OK 🙂
  • Click and hold down on an item for a couple of seconds until the blue selection rectangle updates - OnChange event then triggers on release 😕

 

It's as though if the user releases their mouse button before the selection rectangle moves to the new item (which takes a second or so) then the item is still selected visually as expected, but the accompanying OnChange event fails to fire. 

 

The documentation says FMX.ListView.TListViewBase.OnChange "Occurs when the ItemIndex property changes as a result of a user selecting a different item.  Write an OnChange event handler to respond to changes of the ItemIndex property. OnChange allows a response once the list has been successfully changed."

 

I've tried using the similar OnChangeRepainted event instead, but get the same result.  Has anyone else encountered an issue with TListView OnChange?

 

(In case it is significant I'm using a laptop, so trackpad rather than a mouse)

Edited by Incus J

Share this post


Link to post

OK, I've voted! (and added a comment)

 

Now I have to figure out a workaround.  OnClick seems to fire, but unfortunately it fires before the new selection comes into effect.  So ItemIndex still points to the previous item.  I wonder if there is a way to retrieve the new upcoming index value from within the OnClick event handler?  Or by the time OnMouseUp fires, ItemIndex might have updated by then?

 

Or maybe in OnClick I could call Application.ProcessMessages followed by a call to the OnChange event handler manually.  Could get messy.

Edited by Incus J

Share this post


Link to post

Hi,

 

my temporary solution is : copiing files from delphi 10.3x to local App directory

image.png.c9b5d163748ba7856cb5e715d3adf8de.png

 

br,

M

 

Share this post


Link to post

Oh, I never thought of that.  At the moment the following seems to work but requires two event handlers :

procedure TMainForm.MyListViewChange(Sender: TObject);
begin
  MyController.ShowMatch(MyListView.ItemIndex); //Pass the new index to my code for processing.
end;

procedure TMainForm.MyListViewItemClick(const Sender: TObject;
  const AItem: TListViewItem);
begin
  MyListView.ItemIndex:=AItem.Index; //Set the item index manually.
  MyListView.OnChange(Sender);       //Call the OnChange handler.
end;

So OnChange is the same as before (fired for arrow keys, and also click-and-hold)

OnItemClick fires for a normal mouse click, sets the ItemIndex itself, then simulates an OnChange call.

 

That combination seems to catch all the various ways an item can be selected.  However it's likely OnChange will get called multiple times per selection in some cases (i.e. when Click and Change both fire).

 

There's also a workaround posted in the bug report comments, which looks to achieve the same kind of thing in reverse.

Edited by Incus J

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×