IceCold
IceCold

Reputation: 21194

How to implement OnSelectionChanged event for a TFileListBox?

I want to create a new event for TFileListBox. I want to know when the user selects a different item.

The best way to implement it will be to call the event when the user presses the mouse button like this:

procedure TMyFileList.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
VAR PrevItem: Integer;
begin
 PrevItem:= ItemIndex; <---------- Problem here
 inherited;
 if (Count> 0)
 AND ( PrevItem<> ItemIndex )                                                  
 AND Assigned(FOnSelChaged)
 then FOnSelChaged(Self, PrevItem);
end;

So, let's say the fist item (ItemIndex=0) was already selected. As soon as I push down the mouse button to select the second item, I enter the MouseDown procedure. But here the ItemIndex is already 1 instead of 0. Why?

Upvotes: 3

Views: 476

Answers (1)

David Heffernan
David Heffernan

Reputation: 613302

TFileListBox maintains a protected field named FLastSel which is exactly what you need. The other big problem with your code is that you are assuming that selection can only be changed by the mouse. Don't forget about the keyboard or programmatic modification. You are looking for the virtual method named Change.

So, putting it all together, you can do what you need like this:

TMyFileListBox = class(TFileListBox)
protected
  procedure Change; override;
.... 

procedure TMyFileListBox.Change;
begin
  if (Count>0) and (FLastSel<>ItemIndex) and Assigned(FOnSelChanged) then        
    FOnSelChanged(Self, FLastSel, ItemIndex);
  inherited;
end;

We have to make use of FLastSel before we call the inherited Change method since that is where FLastSel is changed to be equal to the current selection.

procedure TFileListBox.Change;
begin
  FLastSel := ItemIndex;
  .... continues

Upvotes: 6

Related Questions