Mega Code Archive

 
Categories / Delphi / VCL
 

Which column was clicked in a TListView

Title: Which column was clicked in a TListView? Question: How can I know which column was click in a TListView? GetItemAt only works with the first column. Answer: The method GetItemAt only provides the information about which ListItem (if any) is located at the specified coordinates passed as parameters, but only works with the first column of the TListView. The rest are ignored. If we needed to know if the user clicked on an element in another column, we can declare a new method in a derived class: type TListViewX = class(TListView) public function GetItemAtX(X, Y: integer; var Col: integer): TListItem; end; implementation function TListViewX.GetItemAtX(X, Y: integer; var Col: integer): TListItem; var i, n, RelativeX, ColStartX: Integer; ListItem: TlistItem; begin Result := GetItemAt(X, Y); if Result nil then begin Col := 0; // First column end else if (ViewStyle = vsReport) and (TopItem nil) then begin // First, let's try to find the row ListItem := GetItemAt(TopItem.Position.X, Y); if ListItem nil then begin // Now let's try to find the Column RelativeX := X-ListItem.Position.X-BorderWidth; ColStartX := Columns[0].Width; n := Columns.Count - 1; for i := 1 to n do begin if RelativeX if RelativeX StringWidth(ListItem.SubItems[i-1]) then begin Result := ListItem; Col := i; break; end; //if Inc(ColStartX, Columns[i].Width); end; //for end; //if end; //if end; Casting to the new class ------------------------ We don't need to intall this new component and register it in the components palette as we explained in another article ("Adding new methods and properties without registering new components"). Instead, any time we want to access this method, we can just cast the object (for example ListView1) to our new class. For example in a MouseDown event: procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var col: integer; li: TListItem; begin li := TListViewX.GetItemAtX(x, y, col); if li nil then ShowMessage('Column #' + IntToStr(col)); end;