Reputation:
Firemonkey App, Windows and MacOS target.
I need to know what item is selected when a user scroll with the cursor keys or click with the mouse a listview item.
I can react to the mouse click via the onItemClick event, thats fine, also the onItemsChange event is fired when I move the selection with the cursor keys, but the selected property of the listview stays always at nil within that event.
Is this a bug or is there something I miss?
How do I know what item is selected when user use the cursor keys within the control?
Upvotes: 1
Views: 2060
Reputation: 2591
I really do not understand the down votes they are really a ??? to me. However I decided to update my answer and try to make it clearer
First: You need to realize that the OnChange
event is not the only event that you can do this on. The real question is why the GetSelected
getter method fail on the OnItemsChange
event and returns nil
.
The declaration of the selected property is this
property Selected: TListItem read GetSelected write SetSelected;
The check for its getter method is this:
if (FItemIndex >= 0) and (FItemIndex < Adapter.Count) then
return code
else
result := nil;
so clearly something is happening
in the documentation
List item that is currently selected on the list view. This property is nil if no item is selected.
by selected they mean the check above. which raise the following question how this event is fired in the first place. In the documentation it says
Event that occurs after a list of items has been changed.
it means when you alter the existence of the items (delete, add and not change the height or width I have checked this). Furthermore the selected property does not return nil if the event does not alter the selection
the following test could be used
in a form add the following
In the button OnClick event add this
procedure TForm5.Button1Click(Sender: TObject);
var
I: Integer;
begin
for I := 1 to 10 do
listview1.items.add;
end;
In the OnItemsChange event add this
procedure TForm5.ListView1ItemsChange(Sender: TObject);
begin
caption := 'fired'+datetimetostr(now);
if checkbox1.IsChecked then
caption := 'selected item index: '+ inttostr(listview1.Selected.index);
end;
You get the following results
CheckBox.IsChecked = True
you will get an AV because there is nothing to be selectedFrom my view I think you were in the first case (which is very strange that you did not investigate why).
Putting aside what the documentation says about the OnChange
event. As long as you ensure that an item is selected before calling the GetSelected
method you will not have an AV.
Finally: I find it really disappointing that people don't go the extra mile to answer the Why question.
If you don't know why it is failing then how to ensure it will not fail again?.
Upvotes: -1
Reputation: 1165
You are using the wrong event. The OnItemsChange
event is an
Event that occurs after a list of items has been changed.
as the documentation states. Do you change the list of items? No, you don't.
What you are looking for is the OnChange
event:
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.
See the documentation for more details.
Upvotes: 2